[gelöst] Bedingter Haltepunkt mit fpDebug

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1768
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

[gelöst] Bedingter Haltepunkt mit fpDebug

Beitrag von fliegermichl »

Ich bekomme an einer Stelle einen Range Check Error bei der Anweisung

Code: Alles auswählen

 Dec(Parent.Childcount);
Wenn ich auf diese Zeile einen Breakpoint setze und unter Bedingungen Parent.ChildCount = 0 eintrage, dann stoppt die Ausführung bei jedem erreichen des Breakpoints.
Muß ich die bedingten Haltepunkte irgenwo erst aktivieren?
Zuletzt geändert von fliegermichl am Mo 4. Mai 2026, 12:23, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 11304
Registriert: Mo 11. Sep 2006, 19:01

Re: Bedingter Haltepunkt mit fpDebug

Beitrag von theo »

fliegermichl hat geschrieben: Mo 4. Mai 2026, 10:55 Muß ich die bedingten Haltepunkte irgenwo erst aktivieren?
Glaube ich nicht, das funktioniert hier einwandfrei.
Lazarus 4.99 (rev main_4_99-4294-gf0fed54ae5) FPC 3.2.2 x86_64-linux-gtk3

Bist du sicher, dass der Wert überhaupt jemals <> 0 ist?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1768
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Bedingter Haltepunkt mit fpDebug

Beitrag von fliegermichl »

theo hat geschrieben: Mo 4. Mai 2026, 11:24 Bist du sicher, dass der Wert überhaupt jemals <> 0 ist?
Lazarus 4.99 ließ sich bei mir nicht compilieren. Deshalb habe ich jetzt 4.7 installiert.
Lazarus 4.7 (rev lazarus_4_6-57-g80bad76b72) FPC 3.3.1 i386-win32-win32/win64
Ja, der Haltepunkt wird jedesmal aktiviert und wenn ich mir Parent.ChildCount anschaue, hat der anfänglich immer Werte <> 0 und da sollte der Debugger nicht stoppen.

Die Ursache für den RangeError ist mir schon klar. Ich weiss nur nicht, wie es zu dem Fall kommen kann, dass Parent.Childcount = 0 wird, bevor die Node gelöscht wird.

Edit: Wenn man bei der Bedingung Parent^.Childcount = 0 reinschreibt, dann funktioniert es. fpDebug macht die automatische Dereferenzierung von Pointern nicht.

martin_frb
Beiträge: 607
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: [gelöst] Bedingter Haltepunkt mit fpDebug

Beitrag von martin_frb »

FpDebug can pointer auto deref => aber nicht als default.
In den Optionen (Tools > Options > Debugger > Backend) ist im property grid ein Eintrag.

FpDebug "derefed" nur, wenn keine andere option existiert.

MyPointerToArray[1] => kein auto deref, da FPDebug pointers mit index bereits dereferenziert. MyPointerToInt[1] => Zweite int im Memory range wo der Pointer hinzeigt

-----

In Fällen wie diesen, die Bedingung einfach als Watch hinzufügen, und sehen ob es einen Fehler gibt.... Fehlerhafte Bedingungen halten immer.

(Manche) Fehler können abgefangen werden mit

Code: Alles auswählen

:try(condition_that_may_be_an_error, false)
https://wiki.freepascal.org/FpDebug-Wat ... xpr2,_...)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1768
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [gelöst] Bedingter Haltepunkt mit fpDebug

Beitrag von fliegermichl »

martin_frb hat geschrieben: Di 5. Mai 2026, 09:11 FpDebug can pointer auto deref => aber nicht als default.
In den Optionen (Tools > Options > Debugger > Backend) ist im property grid ein Eintrag.

FpDebug "derefed" nur, wenn keine andere option existiert.

MyPointerToArray[1] => kein auto deref, da FPDebug pointers mit index bereits dereferenziert. MyPointerToInt[1] => Zweite int im Memory range wo der Pointer hinzeigt
Ah ok, Danke für die Info
In Fällen wie diesen, die Bedingung einfach als Watch hinzufügen, und sehen ob es einen Fehler gibt.... Fehlerhafte Bedingungen halten immer.

(Manche) Fehler können abgefangen werden mit

Code: Alles auswählen

:try(condition_that_may_be_an_error, false)
https://wiki.freepascal.org/FpDebug-Wat ... xpr2,_...)
Auch gut zu wissen.
In Delphi hält der Debugger an der Stelle an und zeigt eine Hinweismeldung, daß die Bedingung fehlerhaft ist.

martin_frb
Beiträge: 607
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: [gelöst] Bedingter Haltepunkt mit fpDebug

Beitrag von martin_frb »

fliegermichl hat geschrieben: Di 5. Mai 2026, 11:40 In Delphi hält der Debugger an der Stelle an und zeigt eine Hinweismeldung, daß die Bedingung fehlerhaft ist.
Die Anzeige fehlt in Lazarus... Anhalten tut Lazarus => siehe original Beispiel, der deref fehlte, der Breakpoint stoppte.

Wenn jetzt aber ein Breakpoint auf

Code: Alles auswählen

  TButton(Sender).FModalResult = 1
halten soll...

Was wenn Sender gar kein TButton ist?

Ok, der TypeCast forciert das immer. und solange das Memory lesbar ist, gibt es keinen Fehler.

Gegen NIL kann man :Try oder "sender <> nil ? aaa : bbb" nutzen.
:Try(MyButton.FModalResult, false)
bei nil, kann FModalResult nicht gelesen werden.

Für TButton oder nicht

Code: Alles auswählen

:cc(Sender).FModalResult = 1
:cc typecasted zur tatsächlichen Klasse. Wenn das kein TButton ist, dann gibt es kein Feld FModalResult. => Und dann kann :Try den Fehler abfangen.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1768
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [gelöst] Bedingter Haltepunkt mit fpDebug

Beitrag von fliegermichl »

Hmm, so ganz verstehe ich das noch nicht.
Zum testen habe ich zwei Buttons auf dem Formular.
Button1 ruft ganz normal Button1Click auf und in Button2Click rufe ich Button1Click(self); auf.
auf der Zeile mit Showmessage ist der Breakpoint.
Ich habe in den Debuggereinstellungen Funktionsaufrufe erlaubt und wenn ich z.B. auf den Sender prüfen will.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var s : string;
begin
 s := Sender.Classname;
 showmessage(s);
end;

Code: Alles auswählen

Sender.Classname = 'TButton' // geht nicht
Sender^.Classname = 'TButton' // geht nicht
PVmt(Sender)^.vClassName^ = 'TButton' // geht nicht
s = 'TButton' // geht
Auch wenn ich mit der Maus auf Sender.Classname zeige oder Sender.Classname in die zu überwachenden Ausdrücke setze, wird

Code: Alles auswählen

function (self: ^$__vtbl_ptr_type): ShortString AT nil
angezeigt.
Ich muss also immer den Umweg über eine dummy Variable gehen.

martin_frb
Beiträge: 607
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: [gelöst] Bedingter Haltepunkt mit fpDebug

Beitrag von martin_frb »

Funktions Aufrufe gehen nur in Watches.
Hints und Break-conditions rufen keine Funktionen auf.

Allerdings (die "()" sind Pflicht um den Funktions Aufruf zu triggern)

Code: Alles auswählen

Button1.Classname()
Shortstring als Ergebnis ist noch nicht implementiert. (Weil das intern als parameter an die Funktion übergeben werden muss)

----------------------
Folgendes geht.

Code: Alles auswählen

^PVmt(Sender)^^.vClassName^ = 'TButton'
FPC verwendet in neueren Versionen PPVmt. (doppelter Pointer)

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

Je nach dem was in dem Button dann angezeigt werden soll, kann man sich das sparen.

FModalResult kommt (wahrscheinlich) nur in TButton vor.

Code: Alles auswählen

:cc(Sender).FModalResult
gibt für buttons den Wert, und für andere Objecte "Field not found".

Und "Field not found" kann man mit :Try abfangen

z.B. (FState in TCheckBox)

Code: Alles auswählen

:Try(:cc(Sender).FModalResult, :cc(Sender).FState, False)

Antworten