Callstack unvollständig

Für Fragen rund um die Ide und zum Debugger
Antworten
Socke
Lazarusforum e. V.
Beiträge: 3101
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Callstack unvollständig

Beitrag von Socke »

Hallo zusammen,
ich nutze hier zurzeit Lazarus 2.2.0 und FPC 3.2.2, beides mit fpcupdelux V2.2.0h for x86_64-win64-win32 frisch erstellt (jeweils der "stable" branch).

Beim Debuggen mit fpdebug fehlen mir ein paar Zeilen im Callstack. Bspw:

Code: Alles auswählen

#0 TForm1.OnAPIEndpointsChanged(TForm1($0000000001588C40), ooChange, nil) at C:\SAM\Entwicklung\projects\cstools_docu\src\ufrmmain.pas:129
#1 TForm1.FPOObservedChanged(TForm1($0000000001588C40), TObject($0000000001569010), ooChange, Pointer(nil)) at C:\SAM\Entwicklung\projects\cstools_docu\src\ufrmmain.pas:193
#2 TPERSISTENT.FPONOTIFYOBSERVERS(Failed to read data from register, Failed to read data from register, Failed to read data from register, Failed to read data from register) at C:\lazarus\fpcsrc\rtl\objpas\classes\persist.inc:100
#3 TCOLLECTION.ADD(Failed to read data from register) at C:\lazarus\fpcsrc\rtl\objpas\classes\collect.inc:319
#4 TCONTROL.CLICK(TCONTROL($00000000015AB780)) at C:\lazarus\lazarus\lcl\include\control.inc:2957
#5 TBUTTONCONTROL.CLICK(TBUTTONCONTROL($00000000015AB780)) at C:\lazarus\lazarus\lcl\include\buttoncontrol.inc:55
[...]
Ziwschen #4 und #3 fehlt der Eventhandler des Buttons meines Programms. Zwischen #3 und #2 fehlt ganz konkret TCollectionItem.Create, TCollectionItem.SetCollection und TCollection.InsertItem (und ggf. mehr?).
Wo sind die hin und wie bekomme ich die angezeigt?

Mein Programm ist mit -gw3 Dwarf3 (beta) übersetzt, während in fpcupdeluxe sowohl für FPC als auch für Lazarus die Checkboxen "Debug" markiert sein.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

martin_frb
Beiträge: 556
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Callstack unvollständig

Beitrag von martin_frb »

FpDebug in 2.3 sollte das besser machen .... Allerdings, ggf nur mit trunk/fixes fpc. Und nur in Pascal Sources (d.h. Stack im Kernel, Libraries... sind immer noch anfällig)

"Normale" Proceduren (in Pascal) verwenden den RBP Register (FrameBase).

Proceduren kompiliert mit "nostackframe" (oder ähnlichen Settings tun das nicht). Solche Proceduren lassen ggf den RBP Register auf dem Wert des Aufrufenden. Dann wird für solche Proceduren der Aufrufende des Aufrufendens gefunden. Und daher fehlt dann ein Frame.

"TCOLLECTION.ADD" verwendet wahrscheinlich den RBP nicht, daher hat es den RBP wert des fehlenden Handlers. Und der Debugger findet direkt den Caller des Handler.

Socke
Lazarusforum e. V.
Beiträge: 3101
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Callstack unvollständig

Beitrag von Socke »

Das wäre zumindest eine Erklärungsmöglichkeit. Ich prüfe mal, ob ich auf trunk aktualisieren kann - bisher war das nicht geplant.
martin_frb hat geschrieben:
Di 6. Dez 2022, 14:32

"Normale" Proceduren (in Pascal) verwenden den RBP Register (FrameBase).

Proceduren kompiliert mit "nostackframe" (oder ähnlichen Settings tun das nicht). Solche Proceduren lassen ggf den RBP Register auf dem Wert des Aufrufenden. Dann wird für solche Proceduren der Aufrufende des Aufrufendens gefunden. Und daher fehlt dann ein Frame.

"TCOLLECTION.ADD" verwendet wahrscheinlich den RBP nicht, daher hat es den RBP wert des fehlenden Handlers. Und der Debugger findet direkt den Caller des Handler.
Ist TCollection.Add keine "normale" Prozedur/Funktion? Der nostackframe Modifier ist zumindest nicht da.
Ich kann dort auch einen Breakpoint setzen und dort wird die Methode im Call-Stack angezeigt - nicht aber die direkt aufrufenden Methoden (hier wieder TPropsStorage.LoadClassProperty)
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

martin_frb
Beiträge: 556
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Callstack unvollständig

Beitrag von martin_frb »

"Normal" in Verwendung, da ein besseres Wort nicht einfiel.

"nostackframe" ist nur eine Möglichkeit eine Procedure auf den RBP verzichten zu lassen. (IIRC directive / optimization / nicht sicher)


Nochmal zu Erklärung:
Die CPU hat einen Register RBP. Darin speichert eine Procedure (so Sie will...) wo Ihre lokalen variablen auf dem Stack sind. Und indirekt auch wo sich die Rücksprungadresse (zum Caller) befindet.
Der Debugger nutzt diese Rücksprungadresse.

Wenn aber die Procedure den RBP nicht nutzt (und auch nicht ändert) dann enthält er die Daten des Callers (und damit die Rücksprungadresse des Callers).
Wenn mehrere Proceduren das nicht verändern, dann ist der RBP eben von der Procedure mehrere Caller weiter oben.

Wenn der Debugger den Stack erkundet, dann sieht er COLLECTION.ADD.
Und nun muss er den Caller finden. Und schaut auf den RPB. Der gehört aber nicht Collection.ADD.

"nostackframe" (und ähnliches) versteckt nicht die Procedure die keinen Callstack hat, sondern deren Caller.

Ganz lapidar umschrieben: RBP ist der Link zum Caller. Wenn eine Procedure den RBP des Callers behält, behält es auch den Link zu dessen Caller, und macht diesen zum eigenen Link. (Und der RBP kann über mehrere Stackframes unverändert weitergegeben werden, und mehrere Caller verstecken)

---------------------------------------------

In 2.3 nutzt der Debugger von FPC generierte Debug Info zum dekodieren des Stacks. FPC hat da aber Bugs, die erst nach 3.2.2 gefixt wurden.

Antworten