Dummy-Haltepunkt (erledigt)

Für Fragen rund um die Ide und zum Debugger
Antworten
Frank Ranis
Beiträge: 210
Registriert: Do 24. Jan 2013, 21:22

Dummy-Haltepunkt (erledigt)

Beitrag von Frank Ranis »

Hi,

manchmal möchte man beim Debuggen einen Haltepunkt haben , z.B. in einer For-Schleife und findet keine passende Codestelle um diesen zu setzten.
Siehe z.B. im Quelltext unten in der Button1Click .

******

Bisher habe ich dann an der gewünschten Halte-Stelle einfach ein sleep(0); eingebaut , das funzt auch ganz gut.
Siehe z.B. im Quelltext unten in der Button2Click .
Man sollte aber nicht vergessen , nach der Benutzung dieses sleep(0); auch wieder auszuklammern.
Es kann sonst zu bösen Laufzeitverzögerungen kommen , besonders dann , wenn die Routine 1000fach benutzt wird.

******

Habe dann mal anstelle von
sleep(0);
ein
asm nop; end;
eingebaut .

Siehe z.B. im Quelltext unten in der Button3Click .
Das funzt sehr gut .
Sollte man nun das Ausklammern vergessen , ergibt sich kaum ein Laufzeitverlust .
(asm nop; end;) ist aber mit einem Haufen Schreibarbeit verbunden.

******

Leider kennt Freepascal kein NOP (außerhalb von asm), oder ich habe es nicht gefunden !
Deshalb habe ich mir dann eine Mini-Procedure gebaut.

// Dummy nop-Procedure
procedure nop; begin end;

Das benutze ich dann im im Quelltext unten in der Button4Click .
Dann einfach an der gewünschten Stelle ein
nop;
eintragen und den Haltepunkt drauf setzten.
Auch das funzt gut und die Laufzeit ist kaum länger als die (asm nop; end;) Methode.


Am besten ist es natürlich , wenn man den Dummy-Haltepunkt nach der Benutzung wieder ausklammert.

Frage:
Wie macht ihr das , gibt es etwas besseres ?

Gruß

Frank

Anbei das Test-Projekt :

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button3: TButton;
    Button4: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit2: TEdit;
    Edit6: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private

  public
   function schritte:integer;

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

// Dummy nop-Procedure
procedure nop; begin end;

{ TForm1 }

// Anzahl Schritte lesen
function TForm1.schritte: integer;
begin
 result:=strtoint(Edit6.text);
end;

// ohne nop
procedure TForm1.Button1Click(Sender: TObject);
var i,j:integer;
    s,e,d:qword;
begin
 edit1.text:='';
 edit1.Update;
 s:=gettickcount64;
 j:=0;
 for i:=1 to schritte do
  begin
   inc(j);
  end;    // <--- Hier ein Haltepunkt funzt leider nicht
          // Die IDE und der Debugger ignorieren das
 e:=gettickcount64;
 d:=e-s;
 edit1.text:=inttostr(d);
end;

// mit sleep(0) , als Halte-Punkt-Dummy
procedure TForm1.Button2Click(Sender: TObject);
var i,j:integer;
    s,e,d:qword;
begin
 Edit2.text:='';
 Edit2.Update;
 s:=gettickcount64;
 j:=0;
 for i:=1 to schritte do
  begin
   inc(j);
   sleep(0); // <--- Meine bisherige Vogehensweise für einen Dummy-Haltepunkt , weil mir nichts besseres eingefallen war
             // Sollte aber nach Benutzung ausgeklammert werden , wegen recht großen Laufzeitverzögerungen !!!!
  end;
 e:=gettickcount64;
 d:=e-s;
 Edit2.text:=inttostr(d);
end;

//mit asm-nop
procedure TForm1.Button3Click(Sender: TObject);
var i,j:integer;
    s,e,d:qword;
begin
 Edit3.text:='';
 Edit3.Update;
 s:=gettickcount64;
 j:=0;
 for i:=1 to schritte do
  begin
   inc(j);
   asm nop; end; // <--- Das hier als Haltepunkt-Dummy funzt gut , ist aber viel Schreiberei
                 // Auch wenn man es vergisst auszuklammern , hat es kaum Laufzeitnachteile
  end;
 e:=gettickcount64;
 d:=e-s;
 Edit3.text:=inttostr(d);
end;

// mit procedure-nop
procedure TForm1.Button4Click(Sender: TObject);
var i,j:integer;
    s,e,d:qword;
begin
 Edit4.text:='';
 Edit4.Update;
 s:=gettickcount64;
 j:=0;
 for i:=1 to schritte do
  begin
   inc(j);
   nop; // <--- Das hier als Haltepunkt-Dummy funzt auch gut , mit wenig Schreiberei
        // Auch wenn man es vergisst auszuklammern , ist die Laufzeit minimal länger als asm; nop, end;
  end;
 e:=gettickcount64;
 d:=e-s;
 Edit4.text:=inttostr(d);
end;

end.
Dateianhänge
Haltepunkt.zip
(140.26 KiB) 53-mal heruntergeladen
Zuletzt geändert von Frank Ranis am Do 27. Feb 2025, 09:19, insgesamt 1-mal geändert.
www.flz-vortex.de

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Dummy-Haltepunkt

Beitrag von Zvoni »

Errrr.... Einfach bei "Inc(j);" nen Haltepunkt setzen?

Oder ich habs ganz falsch verstanden.

Generell: was spricht gegen eine Compile-Condition?

Code: Alles auswählen

{$IFDEF Debug}nop;{$IFEND}
{$IFDEF Debug}Sleep(0);{$IFEND}
Im dem Moment wo du auf "Release" wechselst, fliegt dein Zeitfresser raus.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

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

Re: Dummy-Haltepunkt

Beitrag von theo »

@Frank Ranis: Wird das nicht rausoptimiert?
So vielleicht:

Code: Alles auswählen

procedure NoOp; inline;
begin
   asm nop end;
end; 
Zusätzlich $IFDEF oder einfach nach Gebrauch löschen.

TSchnuckenbock
Beiträge: 118
Registriert: Do 20. Jul 2017, 23:47
OS, Lazarus, FPC: Win7 und Win10
CPU-Target: xxBit
Wohnort: Südheide (Schnuckenland)

Re: Dummy-Haltepunkt

Beitrag von TSchnuckenbock »

Lokale Variable mit beknacktem und kurzem Namen, der man an der Haltepunktstelle einfach einen Wert zuweist.
Wählt man für sowas immer den gleichen beknackten, kurzen Variablen-Namen, dann findet man die entsprechenden Stellen auch schnell, falls man das alles mal rauswerfen möchte.

Frank Ranis
Beiträge: 210
Registriert: Do 24. Jan 2013, 21:22

Re: Dummy-Haltepunkt (erledigt)

Beitrag von Frank Ranis »

Hi ,

ich danke euch für die Antworten .

Der letzte Tipp von TSchnuckenbock ist derzeit mein Favorit.

Als beknackte Variable habe ich mir

Code: Alles auswählen

var hama:byte=0;
ausgedacht , hama steht für "halt mal" und ist kurz genug .

Die Testschleife sieht dann so aus.

Code: Alles auswählen

// mit beknackter Variable
procedure TForm1.Button5Click(Sender: TObject);
var i,j:integer;
    s,e,d:qword;
    hama:byte=0; // hama(für halt mal) als Dummy-Haltepunkt-Variable
begin
 Edit5.text:='';
 Edit5.Update;
 s:=gettickcount64;
 j:=0;
 for i:=1 to schritte do
  begin
   inc(j);
   hama:=0; // <--- Variable als Haltepunkt-Dummy
            // Auch wenn man es vergisst auszuklammern , ist der Laufzeitunterschied nicht wirklich messbar
            // Funktioniert in allen Optimierungsstufen 0-4
  end;
 e:=gettickcount64;
 d:=e-s;
 Edit5.text:=inttostr(d);
end;       
Vergisst man mal die Halteposition auszuklammern , ist das mit der Dummy-Variable nicht so tragisch.
Ich konnte keinen Laufzeitunterschied feststellen.

Die Dummy-Variable bleibt bei allen Optimierungsstufen (0-4) erhalten , wird also nicht wegoptimiert .

Ein

Code: Alles auswählen

{$IFDEF Debug}  
 hama:=0;
{$IFEND}
kann man ja auch noch einbauen , ist aber mit mehr Schreibarbeit verbunden .

Vielen Dank noch mal .

Gruß

Frank
www.flz-vortex.de

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Dummy-Haltepunkt (erledigt)

Beitrag von Zvoni »

Frank Ranis hat geschrieben: Do 27. Feb 2025, 09:18 Ein

Code: Alles auswählen

{$IFDEF Debug}  
 hama:=0;
{$IFEND}
kann man ja auch noch einbauen , ist aber mit mehr Schreibarbeit verbunden .

Vielen Dank noch mal .

Gruß

Frank

Code: Alles auswählen

program Project1;
{$MACRO ON}
Var hama:Byte=0;
{$define HaltMal:={$IFDEF Debug}hama:=0;{$IFEND}}
begin
  Writeln;
  Haltmal
  Readln;
end.
Breakpoint auf "Haltmal" funzt (IDE reagiert)
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
greye
Beiträge: 45
Registriert: So 16. Feb 2014, 15:38
OS, Lazarus, FPC: Debian/Fedora/Windows, Lazarus 3.6/4.0RC2, FPC 3.2.2
CPU-Target: 64 Bit

Re: Dummy-Haltepunkt (erledigt)

Beitrag von greye »

Frank Ranis hat geschrieben: Do 27. Feb 2025, 09:18 Die Dummy-Variable bleibt bei allen Optimierungsstufen (0-4) erhalten , wird also nicht wegoptimiert .
Spannend. Ich hatte neulich ja mal eine Frage, weil bei O3+ eine Schleife wegoptimiert wurde, die keinen Wert liefert, der außerhalb weiterverarbeitet wird. Ich hätte daher angenommen, daß das bei dieser Variable/der Zuweisung auch so ist.

Kann es sein, daß sie dann nicht wegoptimiert wird, wenn ein Breakpoint drauf sitzt, ansonsten aber schon?

42m

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6763
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dummy-Haltepunkt (erledigt)

Beitrag von af0815 »

greye hat geschrieben: Kann es sein, daß sie dann nicht wegoptimiert wird, wenn ein Breakpoint drauf sitzt, ansonsten aber schon?
Kann nicht sein, da der Compiler nichts vom Debugger weis.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Dummy-Haltepunkt (erledigt)

Beitrag von fliegermichl »

af0815 hat geschrieben: Sa 1. Mär 2025, 20:55
greye hat geschrieben: Kann es sein, daß sie dann nicht wegoptimiert wird, wenn ein Breakpoint drauf sitzt, ansonsten aber schon?
Kann nicht sein, da der Compiler nichts vom Debugger weis.
Sicher? Er compiliert doch im Debug oder Release Mode.

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

Re: Dummy-Haltepunkt (erledigt)

Beitrag von theo »

fliegermichl hat geschrieben: So 2. Mär 2025, 07:56
af0815 hat geschrieben: Sa 1. Mär 2025, 20:55
greye hat geschrieben: Kann es sein, daß sie dann nicht wegoptimiert wird, wenn ein Breakpoint drauf sitzt, ansonsten aber schon?
Kann nicht sein, da der Compiler nichts vom Debugger weis.
Sicher? Er compiliert doch im Debug oder Release Mode.
Ja, du kannst den BP auch setzen, nachdem die Anwendung schon läuft.
Hat also mit dem Compiler nichts zu tun.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6763
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dummy-Haltepunkt (erledigt)

Beitrag von af0815 »

fliegermichl hat geschrieben: So 2. Mär 2025, 07:56
af0815 hat geschrieben: Sa 1. Mär 2025, 20:55
greye hat geschrieben: Kann es sein, daß sie dann nicht wegoptimiert wird, wenn ein Breakpoint drauf sitzt, ansonsten aber schon?
Kann nicht sein, da der Compiler nichts vom Debugger weis.
Sicher? Er compiliert doch im Debug oder Release Mode.
Mit Debugmode - Damit erzeugst du zusätzlichen Code für die Prüfungen bzw. Funktionen die du verwenden willst. Hat nichts mit dem Debugger zu tun, genaugenommen nur insofern, das da Informationen bereitgestellt werden, die ein Debugger nutzen kann um es besser für den Benutzer zu visualisieren.
Mit Releasemode - da lässt man die zusätzlichen Prüfungen und Funktionen weg und erreicht damit normalerweise etwas schnelleren Code (Wenn es der Programmierer nicht grundlegend verbockt hat).

Wobei die Modes reine Vereinbarung sind :-) Und debuggen kann man auch ohne Debuggingfunktionen hineinkompiliert, wenn man sich mit Assembler beschäftigt hat und es unbedingt auf die harte Tour machen will. Da geht es aber auch nicht aus der IDE, dann darf man auf der Kommandozeile arbeiten. Geht alles, ich habe das früher bei den Z80 Prozessoren gemacht, da konnte ich aber den Hexcode auch direkt noch lesen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
greye
Beiträge: 45
Registriert: So 16. Feb 2014, 15:38
OS, Lazarus, FPC: Debian/Fedora/Windows, Lazarus 3.6/4.0RC2, FPC 3.2.2
CPU-Target: 64 Bit

Re: Dummy-Haltepunkt (erledigt)

Beitrag von greye »

Wirklich sehr spannend und lehrreich, was ich hier lese, danke dafür.
Aber die Frage treibt mich trotzdem noch um: Wieso wird die Variable und deren Belegung, die außer ihrem Selbstzweck keinerlei Mehrwert für den weiteren Programmablauf bringt, nicht spätestens ab -O3 "wegoptimiert"?

Tut mir leid, ich frage deshalb so blöd, weil ich, wie geschrieben, genau darüber gestolpert bin, als ich mal schnell ein Progrämmchen schreiben wollte, daß ein paar Millionen mal eine bestimmte mathematische Operation ausführt - einfach, um die benötigte Zeit grob abzuschätzen. Tja, eine Laufzeit von 0,irgendwas Millisekunden oder so kam mir dann doch seltsam schnell vor. Klar, das Programm hat gar nichts gemacht, weil die Schleife "wegoptimiert" wurde, da die Ergebnisse der Berechnungen in der Schleife außerhalb überhaupt keine Rolle spielten. Mit -O0 und -O1, ich meine, auch noch mit -O2, ging es dann wie gewünscht, -O3 und -O4 haben rigoros weggekürzt. Was ist hier anders?

42m

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6763
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dummy-Haltepunkt (erledigt)

Beitrag von af0815 »

Wenn die Variable global ist, wird da IMHO nichts so schnell wegoptimiert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Dummy-Haltepunkt (erledigt)

Beitrag von fliegermichl »

af0815 hat geschrieben: So 2. Mär 2025, 14:18 Wenn die Variable global ist, wird da IMHO nichts so schnell wegoptimiert.
Geht ja auch gar nicht. Wenn die Variable im interface Teil einer unit definiert wird, muss diese erhalten bleiben.

Benutzeravatar
greye
Beiträge: 45
Registriert: So 16. Feb 2014, 15:38
OS, Lazarus, FPC: Debian/Fedora/Windows, Lazarus 3.6/4.0RC2, FPC 3.2.2
CPU-Target: 64 Bit

Re: Dummy-Haltepunkt (erledigt)

Beitrag von greye »

fliegermichl hat geschrieben: So 2. Mär 2025, 15:00 Geht ja auch gar nicht. Wenn die Variable im interface Teil einer unit definiert wird, muss diese erhalten bleiben.
Nur ist das bei den Codefragmenten, die ich hier sehe, nicht der Fall. Nicht mal global ist die Variable.

Aber wie schon andernorts geschrieben, ich steige nach etwa 30 Jahren wieder ein und habe KEINE(!1elf) Ahnung.
Von daher kann ich auch komplett daneben liegen und das Offensichtliche einfach nicht sehen.

42m

Antworten