Problem seit Umstieg auf V1.6

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Problem seit Umstieg auf V1.6

Beitrag von dl5eu »

Hallo zusammen,

vor ein paar Tagen bin ich nach der Neuinstallation meines PCs (Windows 7 64 Bit) auf Lazarus V1.6 32 Bit umgestiegen, vorher hatte ich V1.4.2 installiert. Nachdem ich gelesen hatte, dass sogar eine Anwendung mit etwa 250.000 Zeilen Code keine Probleme machte dachte ich, ich könnte es wagen. Leider funktioniert mein Mini-Programm mit nur zwei Forms seitdem nicht mehr. Auf einem zweiten PC, auf dem noch V1.4.2 läuft, kompiliert und funktioniert das Programm nach wie vor. Vielleicht habt ihr ja eine Idee wo ich suchen muss. Das Problem sitzt wohl mal wieder zwischen Tastatur und Stuhl...

In den Items einer ComboBox speichere ich nicht nur Strings sondern auch damit verknüpfte Objekte (am USB angeschlossene Geräte). Wenn ich nach Interfaces scanne, werden zunächst die alten aus der Liste gelöscht und dann neu gesucht.

Der Teil der scheinbar Probleme macht ist folgender:

// Delete all items from the combobox
for i := 0 to cboInterface.Items.Count - 1 do
TMyUSBInterface(cboInterface.Items.Objects[i]).Free;
cboInterface.Clear;


cboInterface.Items.Count ist 1, da ein Gerät angeschlossen ist (im Debugger verifiziert). Trotzdem wird "Free" nach der Freigabe des Objektes mit Index 0 nochmals aufgerufen, so dass mein Programm ein nicht existierendes Objekt freigeben will. Das funkioniert natürlich nicht (SIGSEGV). In V1.4.2 tritt dieses Problem aber nicht auf :shock:

Hat sich etwas grundlegendes seit der Version 1.4.2 geändert, das ich übersehen habe oder hat jemand von Euch eine Idee, was ich falsch mache?

Vielen Dank für Eure Hilfe!

Beste Grüße,

Ralf (DL5EU)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Problem seit Umstieg auf V1.6

Beitrag von wp_xyz »

Ich glaube eher, dass das Problem schon immer vorhanden war, nur bei 1.4.2 (bzw. von fpc 2.6.4 - denn das dürfte der hier maßgebliche Unterschied sein) nicht ans Tageslicht gekommen ist. Denn wieso soll der Destructor der in den Combobox.Items.Objects gespeicherten TMyUSBInterface-Objekte nach dem Wechsel der IDE/des Compilers zweimal aufgerufen werden? Setze einen Breakpoint im Destructor von TMyUSBInterface (falls es keinen eigenen Destructor gibt, schreibe vorübergehend einen, der nur inherited aufruft). Wenn das Programm dann hier stoppt, prüfe im Aufrufstack ("Ansicht" / "Debugger-Fenster" / "Aufrufstack") von woher der zweite Aufruf kommt - vielleicht gibt es ja irgendwie doch eine andere Stelle, die die USBInterface-Objekte freigeben möchte. Evtl hilft auch, die Combobox.Items.Objects[i] nach deren Free auf nil zu setzen.

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Problem seit Umstieg auf V1.6

Beitrag von dl5eu »

Hallo wp_xyz

und Danke für die schnelle Antwort. Dass der Fehler in meinem Programm schon länger existiert ist natürlich sehr gut möglich.

Wahrscheinlich habe ich mich missverständlich ausgedrückt. Das passiert mir leider immer wieder mal. Wenn ich einen Breakpoint auf dem Destruktor selbst setze, wird der nur tatsächlich nur einmal aufgerufen. Das Problem ist wohl, dass das Programm auf ein nicht existierendes Objekt zugreifen will (nämlich das mit Index i = 1).

Ich habe mir in der for-Schleife den Wert von i und cboInterface.Items.Count mit ShowMessage() anzeigen lassen. Beim Eintritt in die Schleife ist i = 0 und cboInterface.Items.Count = 1. Das Objekt mit Index 0 existiert und kann freigegeben werden. Dann wird die Schleife aber nochmals ausgeführt, obwohl das nach meinem Verständnis nicht sein dürfte, denn i ist dann 1 und cboInterface.Items.Count ebenfalls, es ist also i > (cboInterface.Items.Count - 1) und damit die Schleifenbedingung nicht mehr erfüllt.

Wahrscheinlich wird in meinem Programm durch einen Fehler irgendetwas so verändert, dass die Abbruchbedingung nicht erkannt wird. Da werde ich wohl noch ein bisschen suchen müssen.

Beste Grüße,

Ralf

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Problem seit Umstieg auf V1.6

Beitrag von wp_xyz »

Gibt es irgendwelche Event-Handler etc, die aufgerufen werden, wenn die Objekte zerstört werden?

Unter "Projekt-Optionen" / "Hinzufügungen und Beeinflussungen" (schrecklicher Titel!) klicke auf "Hinzufügen" / "Benutzerdefinierte Option" und trage in der erscheinenden Zeile "Custom" den String "-gw2" ein (ohne "), OK. Damit werden auch die verwendeten Bibliotheken mit Debug-Informationen (Dwarf2) übersetzt und du kommst mit dem Debugger tiefer in die benutzten Routinen rein.

Übersetze das Programm mit Heaptrc ("Projekt-Optionen" / "Debuggen" / Häkchen vor "HeapTrc Unit verwenden" setzen). Das ist zwar ein Tool, um Speicherlecks zu finden, aber oft gehen diese einher mit ungültigen Speicherbereichen, so dass du aus dem Output eine Idee bekommen kannst, wohin du gucken musst.

Werden die erzeugten Objekte nur in der Combobox gespeichert? oder vielleicht doch noch in einer anderen Liste?

Kannst du dein Programm soweit reduzieren, dass alles für den Fehler Unnötige entfernt ist aber der Fehler erhalten bleibt? Dieses reduzierte Programm solltest du hier posten. Ich bin sicher, dass jemand schnell eine Lösung findet. (Zum Posten nur pas, lfm, lpi und lpr Dateien nehmen und in ein gemeinsames zip packen).

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Problem seit Umstieg auf V1.6

Beitrag von dl5eu »

Hallo,

was die Event-Handler betrifft muss ich nachsehen, denn ich habe schon seit längerer Zeit nichts mehr an dem Programm gemacht, da es Teil eines kombinierten Hardware-/Softwareprojekts ist und eigentlich schon fertig war.

Das Programm dient zur Konfiguration eines bestimmten, über USB an den PC angeschlossenen Gerätetyps. Da davon (zumindest theoretisch) mehrere an einem PC angeschlossen sein können, suche ich, wenn der Konfigurationsdialog aufgerufen wird, nach vorhandenen Geräten und trage sie, wenn gefunden, als Objekte in die Combobox ein. Dort kann dann das interessierende Gerät ausgewählt und konfiguriert werden. Mir erschien diese Lösung am einfachsten, aber es ist vielleicht nicht die beste.

Auf jeden Fall danke ich für die Hinweise. Ich werde mich wieder melden, wenn ich den Fehler (hoffentlich) gefunden habe.

Beste Grüße,

Ralf

dl5eu
Beiträge: 33
Registriert: Do 12. Sep 2013, 12:40

Re: Problem seit Umstieg auf V1.6 - Aufruf von Funktionen in

Beitrag von dl5eu »

Hallo zusammen,

das Problem in meinem Programm ist wahrscheinlich ein zerstörter Stack.

Zur Erklärung: Ich verwende eine DLL von FTDI (FTD2xx.dll), für die ich mir eine Wrapper-Unit geschrieben habe. Diese DLL ist (vermutlich) in C oder C++ geschrieben. Als Aufrufkonvention für die externen Funktionen habe ich "cdecl" angegeben, was bisher funktioniert hat.

Nun habe ich in einem anderen Forum gelesen: "stdcall" calling convention is used in the windows api, "cdecl" calling convention is used by both "C" and "C++". Nach der Änderung der Aufrufkonvention der betreffenden Funktionen auf stdcall funktioniert mein Programm scheinbar wieder richtig. Allerdings bin ich nicht sicher, ob das wirklich richtig ist und ich den Unterschied zwischen "cdecl" und "stdcall" verstanden habe. Die erste der aufgerufenen Funktionen, die das Problem verursacht hat, ist folgende:

function FT_CreateDeviceInfoList(var NumDevs: DWord): FT_STATUS; cdecl; external FT_DLL_Name Name 'FT_CreateDeviceInfoList'; // funktioniert nicht
aber
function FT_CreateDeviceInfoList(var NumDevs: DWord): FT_STATUS; stdcall; external FT_DLL_Name Name 'FT_CreateDeviceInfoList'; // funktioniert

Was ist hier richtig bzw. wie muss ich die Funktion deklarieren, damit es richtig ist?

Für mich bedeutete bisher "cdecl", dass die externe Funktion einen Aufruf wie aus einem C-Programm heraus erwartet. Ist das so nicht korrekt? Oder liegt es daran, dass ich "var NumDevs: DWord" anstatt z.B. "NumDevs: Pointer" verwende? Wenn ja, wo liegt der Unterschied? "var" legt doch die Adresse der Variablen auf den Stack, oder nicht? Vielleicht kann jemand von Euch etwas Licht in mein Dunkel bringen ;-) Das Ganze ist etwas verwirrend für mich.

Vielen Dank für Eure Hilfe!

Grüße,

Ralf

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Problem seit Umstieg auf V1.6

Beitrag von Christian »

Wiso machst du dazu keinne neuen Thread auf ? Hat das wirklich was mit dem Thema zu tun ?

FTDI bietet selbst eine Unit an in der die Calling convention sicher stimmt. Benutzt du diese ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Antworten