Watchpoints / Bedingte Breakpoints

Für Fragen rund um die Ide und zum Debugger
Antworten
Socke
Lazarusforum e. V.
Beiträge: 3158
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:

Watchpoints / Bedingte Breakpoints

Beitrag von Socke »

Hallo zusammen,

mit Watchpoints, bedingten Breakpoints oder "Datenhaltepunkte" lässt sich das Debugging von Schleifen erheblich vereinfachen.
Man kann das Programm erst dann anhalten, wenn es den problematischen Schleifenindex erreicht hat und muss sich nicht durch alle vorhergehenden Iterationen hindurcharbeiten.

Ich habe gerade folgende Vorgehensweise erfolgreich getestet:
  1. Normalen Breakpoint vor der Schleife anlegen
  2. Rechtsklick in den Sourcecode "Debug->Datenhaltepunkt..."
  3. In dem Dialog wird eingetragen (um die Schleife mit der Indexvariablen i bei Index 22 anzuhalten):
    Überwachen: i
    Bedingung: i=22
  4. Watchpoint speicher und Programm zum Debuggen starten
  5. Sobald der in Punkt 1 gesetzte normale Breakpoint erreicht ist, kann man im Fenster "Ansicht->Debuggerfenster->Haltepunkte" den in Punkt 2/3 angelegten Watchpoint erneut aktivieren. Beim speichern wurde er vermutlich auf den Status "Invalid (On)" gesetzt, da der Debugger die Variable i nicht gefunden hatte.
  6. Das Programm kann jetzt forgesetzt werden; sobald die Variable i den gewünschten Wert (22) angenommen hat, wird das Programm wieder unterbrochen und man kann wieder Schritt für Schritt weiter debuggen.

Gibt es Möglichkeiten diese Schritte zu vereinfachen? Kann ich irgendwie mitgeben, dass die Variable nur in einer bestimmten Prozedur überwacht werden soll? Mit der Vorgehensweise oben wird nach der Aktivierung das Programm immer häufiger auch außerhalb der fraglichen Prozedur angehalten.
Einen Weg hatte ich über Breakpoint-Gruppen gefunden; damit muss ich zur Überwachung einer Variablen aber zwei Breakpoints (jeweils vor und nach der Schleife) den Watchpoint ein- bzw. ausschalten. Wirklich effizient arbeiten kann man damit nicht.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

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

Re: Watchpoints / Bedingte Breakpoints

Beitrag von wp_xyz »

Dass ein bedingter Breakpoint deaktiviert worden ist (also grün wird), habe ich noch nicht gesehen. Allerdings ist es "Glückssache", ob das Programm wirklich an dem bedingten Breakpoint anhält. Vor allem bei Strings weiß ich nicht, wie man das eingeben muss.

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var
  i, j: Integer;
  s: String;
  n: Integer;
begin
  n := 0;
  for i:= 1 to 10 do
    for j := 1 to 10 do begin
      s := IntToStr(i) + IntToStr(j);
      inc(n);               //<--- Breakpoint hier setzen
    end;
  Caption := s;
end;

Setze ich im obigen Beispiel einen Breakpoint auf "inc(n)", so hält das Programm einwandfrei, wenn die Bedingung "i=5" ist, oder auch "(i=5) and (j=1)". Die Bedingung "s='51'" wird dagegen nicht erkannt.

Daher schreibe ich manchmal triviale Bedingungen in den Code, a la

Code: Alles auswählen

if s = '51' then 
  s := s + '';    // <--- Breakpoint hier setzen

und setze den Breakpoint (nun ohne Bedingung) auf die Anweisung im then-Zweig (der in einer separaten Zeile stehen muss). Leider besteht dabei natürlich die Gefahr, dass man nach längerer Fehlersuche vergisst, dies wieder zu löschen.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Watchpoints / Bedingte Breakpoints

Beitrag von mse »

Watchpoints werden ungültig, sobald das Programm den Scope der überwachten Variable verlässt, sie eignen sich also vor allem für globale Variablen oder Werte auf dem Heap. Watchpoints werden von gdb ebenfalls deaktiviert, wenn gdb den überwachten Ausdruck aus irgend einem Grund nicht auswerten kann. MSEide hat darum im Watches-Fenster den Popup-Menu Eintrag 'Address Watchpoint *' welcher einen Watchpoint mit der Addresse des im Watch Fenster in der aktuellen Zeile angezeigten Ausdruckes erzeugt. Der Address-Watchpoint verliert seine Gültigkeit während des Programmlaufs nicht.

Code: Alles auswählen

 
 tmainfo = class(tmainform)
[...]
  protected
   ftest: int32;
 end;
 
 

watchpoint.png

watchpoint1.png

Für gdb Hilfsvariablen verwende ich immer Namen die mit "testvar" beginnen. 'Search'-'Find in Files' listet dann vergessene Debug-Zeilen.
testvar.png

Socke
Lazarusforum e. V.
Beiträge: 3158
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: Watchpoints / Bedingte Breakpoints

Beitrag von Socke »

wp_xyz hat geschrieben:Dass ein bedingter Breakpoint deaktiviert worden ist (also grün wird), habe ich noch nicht gesehen. Allerdings ist es "Glückssache", ob das Programm wirklich an dem bedingten Breakpoint anhält.

Bei dem obigen Beispiel wird der Watchpoint zuerst mit dem dem Status "Invalid (On)" angelegt, da gdb in der Regel die Variable i im aktuellen Scope nicht finden wird. Daher muss man den Watchpoint beim Eintritt in die fragliche Prozedur nochmals aktivieren
wp_xyz hat geschrieben:Vor allem bei Strings weiß ich nicht, wie man das eingeben muss.

Laut Wiki sind Strings nicht direkt vergleichbar: http://wiki.lazarus.freepascal.org/IDE_ ... properties

mse hat geschrieben:MSEide hat darum im Watches-Fenster den Popup-Menu Eintrag 'Address Watchpoint *' welcher einen Watchpoint mit der Addresse des im Watch Fenster in der aktuellen Zeile angezeigten Ausdruckes erzeugt. Der Address-Watchpoint verliert seine Gültigkeit während des Programmlaufs nicht.

Das Thema hatte ich bewusst unter dem Forum "Lazarus-IDE" eröffnet.

Auch in Lazarus kann man einen Watchpoint auf eine Adresse anlegen, nur kann sich die mit jedem Kompilieren ändern ...
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Watchpoints / Bedingte Breakpoints

Beitrag von mse »

Socke hat geschrieben:Auch in Lazarus kann man einen Watchpoint auf eine Adresse anlegen, nur kann sich die mit jedem Kompilieren ändern ...

Das ist unvermeidlich. Wenn man keine Kompilierung vorgenommen hat, kann man den bestehenden Addresswatchpoint beim erstbesten Programmstop aktiv schalten. Bei Werten im Heap muss sichergestellt sein, dass die Daten bereits angelegt wurden.
Dies zeigt auch den Grund auf, warum Watchpoints beim Programmstart inaktiv sind. Watchpoints sind für gdb überwachte Datenadressen welche beim Programmstart noch nicht bekannt sind.

martin_frb
Beiträge: 571
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: Watchpoints / Bedingte Breakpoints

Beitrag von martin_frb »

Zur Eigentlichen Frage: Anhalten in einer Schleife, wenn i = 22.

Da braucht man keinen Watchpoint. Normale Breakpoints haben auch Bedingungen. (breakpoint rechts anklicken > Breakpoint Properties)

Den Breakpoint auf die erste Zeile *in* der Schleife setzen.

Socke
Lazarusforum e. V.
Beiträge: 3158
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: Watchpoints / Bedingte Breakpoints

Beitrag von Socke »

martin_frb hat geschrieben:Da braucht man keinen Watchpoint. Normale Breakpoints haben auch Bedingungen. (breakpoint rechts anklicken > Breakpoint Properties)

Den Breakpoint auf die erste Zeile *in* der Schleife setzen.

Vielen Dank! Das ist wirklich eine sehr einfache Lösung

Damit halte ich fest:
  • Datenhaltepunkte sind für globale Variablen geeignet (ggf. noch thread-globale Variablen?)
  • Lokale Variablen kann man über normale Zeilenbreakpoints und deren Eigenschaften abdecken
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Watchpoints / Bedingte Breakpoints

Beitrag von mse »

Sorry, es war mir nicht bewusst, dass du bedingte Breakpoints nicht kanntest. Breakpoints mit Bedingungen funktionieren auch für globale Variablen.
Watchpoints werden z.B. dann benötigt, wenn man herausfinden will, wo in einem komplexen Programm eine Variable verändert wird die nicht verändert werden sollte, z.B. durch einen wildgewordenen Pointer oder falsche Programmlogik. Das heisst man setzt einen Watchpoint dort im Programm wo die Variable gesetzt wird, das Programm wird danach vom Debbugger an dem Ort gestoppt, wo die Variable überschrieben wird.

Eine weitere nützliche Eigenschaft von Breakpoints ist 'Ignore'.
Nehmen wir an, es gibt in einem komplexen Programm eine Exception. Wir vermuten, dass die Problemursache in einer nicht im Aufrufstack liegenden Routine liegt. Allerdings tritt das Problem erst nach einigen hundert Aufrufen auf. Das setzen eines Breakpoints in die Problemroutine stoppt die Ausführung am kritischen Ort.
Um nun nicht hunderte mal die Situation am Breakpoint analysieren zu müssen bevor die Exception auftritt, setzen wir 'Ignore' auf eine genügend grosse Zahl und starten das Programm neu. Wenn die Exception auftritt schauen wir im Breakpointfenster wie häufig der Breakpoint ausgelöst wurde und setzen 'Ignore' auf eins weniger. Wenn 'Count' 478 anzeigt, setzen wir 'Ignore' auf 477. Nach einem Neustart wird das Programm beim letzten Aufruf der kritischen Stelle gestoppt bevor die Exception ausgelöst wird.
Bedingung für dieses Vorgehen ist, dass der Programmablauf bei jedem Programmstart gleich ist.

Thandor
Beiträge: 153
Registriert: Sa 30. Jan 2010, 18:17
OS, Lazarus, FPC: Windows 10 64Bit/ lazarus 3.0 mit FPC 3.2.2 (32Bit + 64bit)
CPU-Target: 64Bit
Wohnort: Berlin

Re: Watchpoints / Bedingte Breakpoints

Beitrag von Thandor »

Cool, dass mann Haltepunkte eine Bedingung geben kann, wusste ich auch noch nicht. Vielen Dank.

Socke
Lazarusforum e. V.
Beiträge: 3158
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: Watchpoints / Bedingte Breakpoints

Beitrag von Socke »

mse hat geschrieben:Sorry, es war mir nicht bewusst, dass du bedingte Breakpoints nicht kanntest.

Ich hatte versucht, meine Frage möglichst ergebnisoffen zu stellen. Ich danke dir jedenfalls für die ausführliche Beschreibung.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

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

Re: Watchpoints / Bedingte Breakpoints

Beitrag von fliegermichl »

Ha, Ignore kannte ich auch noch nicht. In Delphi hiess dass Durchlaufzähler und ich hatte diese Funktion in Lazarus schmerzlich vermisst :-)

Antworten