Watchpoints / Bedingte Breakpoints

Für Fragen rund um die Ide und zum Debugger

Watchpoints / Bedingte Breakpoints

Beitragvon Socke » 14. Aug 2018, 20:38 Watchpoints / Bedingte Breakpoints

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
Socke
Lazarusforum e. V.
 
Beiträge: 2592
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon wp_xyz » 14. Aug 2018, 21:32 Re: Watchpoints / Bedingte Breakpoints

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.
wp_xyz
 
Beiträge: 2894
Registriert: 8. Apr 2011, 08:01

Beitragvon mse » 15. Aug 2018, 07:16 Re: Watchpoints / Bedingte Breakpoints

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
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
mse
 
Beiträge: 2013
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon Socke » 15. Aug 2018, 09:39 Re: Watchpoints / Bedingte Breakpoints

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
Socke
Lazarusforum e. V.
 
Beiträge: 2592
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon mse » 15. Aug 2018, 10:05 Re: Watchpoints / Bedingte Breakpoints

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.
mse
 
Beiträge: 2013
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon martin_frb » 17. Aug 2018, 19:37 Re: Watchpoints / Bedingte Breakpoints

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.
martin_frb
 
Beiträge: 440
Registriert: 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other | 
CPU-Target: mostly 32 bit
Nach oben

Beitragvon Socke » 18. Aug 2018, 00:30 Re: Watchpoints / Bedingte Breakpoints

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
Socke
Lazarusforum e. V.
 
Beiträge: 2592
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon mse » 18. Aug 2018, 06:59 Re: Watchpoints / Bedingte Breakpoints

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.
mse
 
Beiträge: 2013
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon Thandor » 19. Aug 2018, 09:55 Re: Watchpoints / Bedingte Breakpoints

Cool, dass mann Haltepunkte eine Bedingung geben kann, wusste ich auch noch nicht. Vielen Dank.
Thandor
 
Beiträge: 118
Registriert: 30. Jan 2010, 18:17
Wohnort: Berlin
OS, Lazarus, FPC: Windows 10 64Bit/ lazarus 1.6 mit FPC 3.0.0 (32Bit) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Socke » 19. Aug 2018, 12:03 Re: Watchpoints / Bedingte Breakpoints

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
Socke
Lazarusforum e. V.
 
Beiträge: 2592
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon fliegermichl » 21. Aug 2018, 12:28 Re: Watchpoints / Bedingte Breakpoints

Ha, Ignore kannte ich auch noch nicht. In Delphi hiess dass Durchlaufzähler und ich hatte diese Funktion in Lazarus schmerzlich vermisst :-)
fliegermichl
 
Beiträge: 312
Registriert: 9. Jun 2011, 08:42

• Themenende •

Zurück zu Benutzung der IDE



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried