Bedingter Haltepunkt.

Für Fragen rund um die Ide und zum Debugger
haderlump
Beiträge: 185
Registriert: Fr 18. Jan 2013, 09:29
OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
CPU-Target: Celeron

Bedingter Haltepunkt.

Beitrag von haderlump »

Hallo zusammen
Ich bräuchte einen Haltepunkt der nur anspricht, wenn ein Feld einen bestimmten Wert hat.
Ich habe also einen Haltepunkt gesetzt, und bin mit der RMT auf Haltepunkt-Eigenschaften gegangen.
Dort habe ich in das Bedingungsfeld " element^.name = 'ADorf Gl2.1 ' " eingegeben.
Der Debugger hält aber immer an, auch wenn die Bedingung nicht erfüllt ist.
Was habe ich da übersehen, oder falsch gemacht?
Bild

Gruß Fritz

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

Re: Bedingter Haltepunkt.

Beitrag von fliegermichl »

Hallo Fritz,

mit dem Debugger und Lazarus bin ich auch nicht so glücklich. Da ist mein 20 Jahre altes Delphi5 10 mal besser. (Anzeigen von properties z.B.)
Ich mach das mittlerweile so, dass ich entweder den Quellcode entsprechend anpasse oder mittels SendDebug (unit dbugintf) mir Nachrichten senden lasse.
Für SendDebug muss zuvor das Projekt <lazarus>\tools\debugserver\debugserver.lpi compiliert und gestartet werden.

Etwa so:

Code: Alles auswählen

 
if element^.name = 'ADorf Gl12.1   ' then
begin
 SendDebug(element^.name); // Das oder hier dann einen Breakpoint ohne Bedingungen setzen
end;
 


LG Michael

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

Re: Bedingter Haltepunkt.

Beitrag von wp_xyz »

Ich will's mal positiv ausdrücken: Die bedingten Breakpoints funktionieren, aber nicht bei Strings, zumindest habe ich noch keine Aufrufsystematik herausgefunden. Ich schreibe stattdessen die Bedingung als "IF" direkt in den Quelltext, mache in dem IF eine triviale Modifikation einer Variablen und setze darauf einen normalen Breakpoint. Also:

Code: Alles auswählen

var
  i: Integer;
...
  if element^.name = 'ADorf Gl12.1   ' then
    i := i+1-1//<---- hier normalen Breakpoint setzen
 

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Bedingter Haltepunkt.

Beitrag von Dee »

Ein Auszug aus dem Lazarus-Wiki:

Breakpoint properties - Condition
...
NOTE #2: Strings can not be compared. They are seen as pchar, so they can only be compared to an address: "str=0x5a0b40". But chars in a string can be compared (index is zero based/pchar) "(s[0]='a')and(s[1]='b')".


Link: http://wiki.lazarus.freepascal.org/IDE_Window:Breakpoint_properties

Ich wusste das bisher auch nicht, bis ich deinen Beitrag gesehen habe. Finde ich ziemlich jämmerlich, dass das nicht möglich ist.

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

Re: Bedingter Haltepunkt.

Beitrag von theo »

Dee hat geschrieben:Finde ich ziemlich jämmerlich, dass das nicht möglich ist.

Das wäre doch ein Job für dich, das zu verbessern, damit es nicht mehr "jämmerlich" ist?
Vielleicht musst du bei GDB beginnen, keine Ahnung. https://www.gnu.org/software/gdb/

haderlump
Beiträge: 185
Registriert: Fr 18. Jan 2013, 09:29
OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
CPU-Target: Celeron

Re: Bedingter Haltepunkt.

Beitrag von haderlump »

Jetzt bin ich direkt beruhigt, ich bin doch kein Depp :lol:
wp_yyz und Fliegermichel ihr habt mir schon weiter geholfen.

Danke
Fritz

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Bedingter Haltepunkt.

Beitrag von Dee »

Nach stundenlangem Recherchieren und Rumprobieren, habe ich eine (weitere) Lösung gefunden.

Code: Alles auswählen

 
{1}    procedure THauptFormular.TesteHaltePunktClick(Sender: TObject);
{2}    var
{3}      Element: PElemente;
{4}      ElementReferenz: TElemente;
{5} 
{6}      // Debug-Variablen
{7}      Debug_HalteWert: String = 'ADorf Gl2.1 ';
{8}    begin
{9}     Element := @ElementReferenz;
{10}    Element^.Name := EditEingabeFeld.Text;
{11}    Now;   // bedingter Haltepunkt: Element^.Name = 'ADorf Gl2.1 '
{12}   end;
 


Bedingung für Haltepunkt:

UTF8CompareStr(Element^.Name, Debug_HalteWert) = 0


In der Zeile 11 würde dann der Haltepunkt eingefügt. Das Now dient für die bessere Lesbarkeit und Orientierung. Ich hätte lieber nur den Kommentar stehen, aber dann greift der Haltepunkt erst eine Anweisung später und das kann bedeuten, wenn das Ende der Methode erreicht ist, der Haltepunkt trotzdem ausgeführt wird. So ist sichergestellt, dass der Haltepunkt richtig ausgelöst wird.
Man könnte statt Now eine eigene (leere) Methode schreiben, die als Platzhalter dient und einen aussagekräftigeren Namen hat, welcher sich auf den Haltepunkt bezieht.

-- Dee

haderlump
Beiträge: 185
Registriert: Fr 18. Jan 2013, 09:29
OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
CPU-Target: Celeron

Re: Bedingter Haltepunkt.

Beitrag von haderlump »

Danke, da is für mich schom was dabei.
Gruß Fritz

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Bedingter Haltepunkt.

Beitrag von mschnell »

theo hat geschrieben:Vielleicht musst du bei GDB beginnen, keine Ahnung. https://www.gnu.org/software/gdb/

Es dürfte ziemlich schwierig sein, dem GDB Pascal String Typen beizubringen :(
-Michael

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Bedingter Haltepunkt.

Beitrag von Dee »

mschnell hat geschrieben:Es dürfte ziemlich schwierig sein, dem GDB Pascal String Typen beizubringen :(

Schade, denn ich war durch theo so hochmotiviert und kurz davor, dieses Problem anzugehen, aber dann lese ich, dass das nicht leich sein wird. Naja, kann man nichts machen. Dann lasse ich das lieber, denn vor schwierigen Sachen halte ich mich lieber fern.

Nein, aber im Ernst: Warum ist das so schwer? Wo liegt das Problem? Das würde mich interessieren.

Edit: Nichts gegen dich, theo. Vielleicht war meine Wortwahl nicht ganz passend. Ich bin einfach nur enttäuscht, dass man in Lazarus keine Strings via Haltepunkte vergleichen kann, da es doch scheinbar so trivial zu sein vermag. Und dass es seitens des Lazarus-Teams keine passende Lösung gibt, finde ich auch enttäuschend.
Immerhin gibt es die Möglichkeit, zeichenweise zu vergleichen, aber könnte man dann nicht einfach eine Schleife nutzen, die dann eben jedes Zeichen mit den Zeichen des zu vergleichenden Strings, vergleicht? Nur ein naiver Gedanke.

-- Dee

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

Re: Bedingter Haltepunkt.

Beitrag von fliegermichl »

Aber PChar ist doch weitestgehend gleich mit char * in C oder etwa nicht?

Edit: Ja ist es. Man kann "utf8comparetext(edit1.Text, 'Hallo Welt') = 0" in die Bedingung schreiben und der Debugger hält brav an wenn man "Hallo Welt" in das Edit schreibt.

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Bedingter Haltepunkt.

Beitrag von Dee »

fliegermichl hat geschrieben:Aber PChar ist doch weitestgehend gleich mit char * in C oder etwa nicht?

Edit: Ja ist es. Man kann "utf8comparetext(edit1.Text, 'Hallo Welt') = 0" in die Bedingung schreiben und der Debugger hält brav an wenn man "Hallo Welt" in das Edit schreibt.

Leider wird der Haltepunkt immer ausgelöst, egal welche String-Werte verwendet werden, womit wir wieder beim ursprünglichen Problem wären.

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

Re: Bedingter Haltepunkt.

Beitrag von fliegermichl »

Tatsache,

ich hab mal ein kleines C Programm gemacht

Code: Alles auswählen

 
#include <stdio.h>
 
int main(int argc, char *args)
{
 char *s = "Hallo Welt";
 printf(s);
 return 0;
}
 


Das compiliert mit gcc -g dbg.c -o dbg.exe
Dann gdb dbg.exe

Code: Alles auswählen

 
b 5
r
b6 if strcmp(s, "Hallo") = 0
cont
 
Ausgabe:
Continuing.
Hallo Welt[Inferior 1 (process 8632) exited normally]
 


Dann nochmal das gleiche aber hinter Hallo dann noch " Welt" und der gdb hält korrekt an. Vorraussetzung ist, daß das Programm bereits gestartet sein muss, da gdb ansonsten meckert, dass er strcmp nicht finden kann.

Es muss doch irgendwie möglich sein dem gdb PChar und das strcmp unterzujubeln?

Dee
Beiträge: 54
Registriert: Do 10. Jul 2014, 20:56
OS, Lazarus, FPC: Windows 10 Pro 64-bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: Ryzen 5 2600

Re: Bedingter Haltepunkt.

Beitrag von Dee »

Danke fliegermichl, für deine Mühe.
Falls du eine GUI haben möchest für gdb, habe ich folgendes gefunden:

https://github.com/cs01/gdbgui

Im Verzeichnis downloads\windows die EXE runterladen und den Pfad der gdb.exe von Lazarus (bspw. "C:\lazarus\mingw\x86_64-win64\bin") in der systemweiten Umgebungsvariable PATH einfügen. Dann die gdbgui-EXE starten und los geht's!

Code: Alles auswählen

(gdb) set language pascal

Nicht vergessen, diesen Befehl einzugeben, weil sonst standardgemäß die C ausgewählt ist. Vielleicht weißt du das aber auch schon.

Ich habe auch ein wenig rumprobiert, aber werde einfach nicht schlau daraus. Unter bestimmten Bedingungen kann man die C-Funktion strcmp() nutzen. Teilweise gibt es "segment faults", wenn ich Vergleichs-Funktionen, wie UTF8CompareText() oder strcmp(), aufrufe; teilweise sogar in Windows-DLLs, was wohl daran liegt, dass eben Funktionen aus diesen DLLs genutzt werden, aber warum die Fehler auftreten - Keine Ahnung. "Adress out of bounds" habe ich auch gehabt, wenn ich String-Literale zum Vergleich nutzen wollte, bspw. in UTF8CompareStr().

Also würde ich schlussfolgern, dass das Problem mit den String-Literalen zu tun hat. Die haben scheinbar keine gültige Adresse, falls die überhaupt eine Adresse haben sollten. Jedenfalls wird, wenn man das Fenster der Lazarus-IDE "Liste überwachter Ausrücke" verwendet, keine Adresse angezeigt, weil:

Code: Alles auswählen

Can't take adress of \<beliebiger Konstanten-Bezeichner> which isn't an lvalue.

Wohl ein paar Schreibfehler drin. Vergleiche mit einem einzelnen Zeichen scheinen zu funktionieren (s = 'a'), aber nicht immer, weil dann "Adress out of bounds" kommt. Vielleicht werde ich noch im Verlaufe des Tages weiteres zu posten.

-- Dee

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Bedingter Haltepunkt.

Beitrag von mschnell »

fliegermichl hat geschrieben:Vorraussetzung ist, daß das Programm bereits gestartet sein muss, da gdb ansonsten meckert, dass er strcmp nicht finden kann.
Es muss doch irgendwie möglich sein dem gdb PChar und das strcmp unterzujubeln?


Wenn der Debugger ein beliebiges Unterprogramm (hier strcmp) aufrufen kann, das im gedebugten Programmcode existiert, sollte das auch mit einer entsprechenden FPC-Funktion wie z.B. "UTF8CompareStr" gehen ??? Es kann aber sein, dass der Debugger die Pascal-Aufrufkonvention für Strings nicht (richtig) kann. Dann könnte man vielleicht eine spezielle Funktion um Code unterbringen. die explizite Aufruf-Konventionen verwendet und dann UTF8CompareStr aufruft.

Oder vielliecht muss man dann so etwas wie

b6 if mycompare(PChar(s), PChar("Hallo")) = 0

schreiben...

-Michael

Antworten