Ausgabe von Komponenten-Inhalten
Ausgabe von Komponenten-Inhalten
Wenn ich in beim Debuggen meine Programms mit der Maus über eine Variable gehen, wird mir dessen Inhalt in einem gelben Hint-Fenster angezeigt. Soweit so gut. Mach ich das bei einer Komponente, bekomme ich dies nicht.
Vereinfachtes Beispiel: eine Komponente "edName" vom Typ TEdit: edName.Caption := 'Hallo';
Behauptet mir der Debugger immer (in dem gelben Hint-Fenster);
"edName.Caption = TYPE TEDIT has no Component named Caption"
Ich habe mir bisher geholfen in einem solchen Fall mir eine Variable vom Typ String anzulegen, dort den Wert zu abzulegen, damit ich mir den Inhalt anschauen kann, der dem Caption zugewiesen wird. Das Problem betrifft absolut alle Komponenten, die ich benutze.
Debugger: $(LazarusDir)\mingw\$(TargetCPU)-$(TargetOS)\bin\gdb.exe
Gibt da irgendwo einen Schalter, den ich setzen muss, damit ich den Inhalt von Caption im Hint-Fenster sehe sehe?
Ich weis, dass ich das früher mal konnte. Seit meiner Neuinstallation Version 2.0.6 Datum 30.03.2020 FPC 3.0.4 SNV 62192 geht das nicht mehr.
Vereinfachtes Beispiel: eine Komponente "edName" vom Typ TEdit: edName.Caption := 'Hallo';
Behauptet mir der Debugger immer (in dem gelben Hint-Fenster);
"edName.Caption = TYPE TEDIT has no Component named Caption"
Ich habe mir bisher geholfen in einem solchen Fall mir eine Variable vom Typ String anzulegen, dort den Wert zu abzulegen, damit ich mir den Inhalt anschauen kann, der dem Caption zugewiesen wird. Das Problem betrifft absolut alle Komponenten, die ich benutze.
Debugger: $(LazarusDir)\mingw\$(TargetCPU)-$(TargetOS)\bin\gdb.exe
Gibt da irgendwo einen Schalter, den ich setzen muss, damit ich den Inhalt von Caption im Hint-Fenster sehe sehe?
Ich weis, dass ich das früher mal konnte. Seit meiner Neuinstallation Version 2.0.6 Datum 30.03.2020 FPC 3.0.4 SNV 62192 geht das nicht mehr.
- 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: Ausgabe von Komponenten-Inhalten
Der Debugger kann keine Inhalte von Properties anzeigen die eine Getter Methode haben. Das ist schon sehr traurig. Mein altes Delphi 5 von 1998 kann das problemlos.
-
- Beiträge: 945
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Ausgabe von Komponenten-Inhalten
Martin Friebe (welcher unter anderem an der Schnittstelle für GDB in Lazarus arbeitet) hat vor ein paar Monaten mal ausführlich erklärt warum das der Fall ist, ich finde jedoch den Beitrag nicht mehr (ganz davon abgesehen, dass ich nicht einmal mehr weiß, ob es hier, im englischen Forum, im Bugtracker oder auf einer der Mailing Listen war).fliegermichl hat geschrieben: Fr 18. Sep 2020, 08:51 Der Debugger kann keine Inhalte von Properties anzeigen die eine Getter Methode haben. Das ist schon sehr traurig. Mein altes Delphi 5 von 1998 kann das problemlos.
Kurz zusammen gefasst:
- Die Debuginformation von FPC ist noch nicht vollständig genug, so dass dies korrekt ausgewertet werden könnte
- Der Debugger muss im Grunde einen Funktionsaufruf durchführen, dazu muss der passende Kontext inklusive Stack angelegt werden (GDB kann das im Grunde, aber das heißt nicht, dass da nicht noch einiges an Handarbeit ist)
- Dann muss sichergestellt werden, dass ein Getter der nicht so handzam ist, nicht alles hängen lässt
- Außerdem ist zu beachten, dass der Aufruf eines Getters auch den Zustand eines Programms ändern kann (zum Beispiel Lazy Initialization von Feldern)
FPC Compiler Entwickler
Re: Ausgabe von Komponenten-Inhalten
Ok. Dann ist nicht falsch bei mir eingestellt.
Mann kann sich ja mit Dummy-Variablen behelfen. Man darf nur nicht vergessen sie wieder aufzuräumen.
Der Compiler hilft ja außerdem beim Aufräumen ungenutzter Variablen.
Mann kann sich ja mit Dummy-Variablen behelfen. Man darf nur nicht vergessen sie wieder aufzuräumen.
Der Compiler hilft ja außerdem beim Aufräumen ungenutzter Variablen.
- 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: Ausgabe von Komponenten-Inhalten
Ich wollte auf keinen Fall FPC oder Lazarus schlecht machen - im Gegenteil.
Das für das auslesen von Properties mit Getter Methoden Funktionsaufrufe stattfinden müssen ist klar.
Auch in Delphi muß ich dafür extra eine Option aktivieren.
Wenn ich für Lazarus bzw. FPC einen Wunsch abgeben könnte, wäre für mich dieser Punkt der mit der höchsten Priorität.
Ich habe allerhöchsten Respekt für die Entwickler von Lazarus und FPC eben weil es Hobbyprojekte sind.
Das für das auslesen von Properties mit Getter Methoden Funktionsaufrufe stattfinden müssen ist klar.
Auch in Delphi muß ich dafür extra eine Option aktivieren.
Wenn ich für Lazarus bzw. FPC einen Wunsch abgeben könnte, wäre für mich dieser Punkt der mit der höchsten Priorität.
Ich habe allerhöchsten Respekt für die Entwickler von Lazarus und FPC eben weil es Hobbyprojekte sind.
-
- Beiträge: 1058
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Ausgabe von Komponenten-Inhalten
oder für debug-Zwecke gleich mit bedingter Kompilierung arbeiten
https://wiki.freepascal.org/Conditional_compilation[url]
[/url]
Code: Alles auswählen
{$IFDEF DEBUG}
MyDummy:=125;
{$ENDIF}
[/url]
Re: Ausgabe von Komponenten-Inhalten
Richtige Männer brauchen keine Debugger! 
SCNR

SCNR
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2805
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Ausgabe von Komponenten-Inhalten
Du kannst dir auch häufig den Umweg über eine temporäre Variable ersparen.
Mit Strg+Alt+W kannst du das Fenster für überwachte Ausdrücke aufrufen. Dort fügst du einen neuen hinzu und benutzt dabei nicht die Property sondern das dahinterliegende Feld, welches die Daten enthält. Für die Caption eines Buttons wäre der gesuchte Ausdruck dann Button1.FCaption. Wenn du nun mit dem Debugger durchstepst, dann siehst du im Fenster immer den aktuellen Wert.

Wie kommt man an diesen Feldnamen?
Bei Caption wird GetText bemüht zum Lesen der Daten. Und die sieht so aus:
Das sieht natürlich weniger schön aus. Mit ein bisschen Suchen finden wir in der 10. Zeile, dass (im Standardfall) RealGetText aufgerufen wird. Die sieht schon etwas übersichtlicher aus:
Das Daten für die Property stehen also in FCaption.
Warum ist das alles so umständlich und warum kann der Debugger nicht einfach GetText aufrufen?
Das liegt an der Gefahr einen Seiteneffekt auszulösen:
Dieser Getter inkrementiert bei jeden Aufruf einen Counter um die Anzahl der Getter-Aufrufe zu loggen. Jedesmal wenn der Debugger die zugehörige Property zugreift, würde das auch passieren. Damit ist der Wert in ReadCount höher als ohne Debuggereinsatz, das Programm verhält sich also mit Debugger anders als ohne. Das sollte man möglichst vermeiden.
Mit Strg+Alt+W kannst du das Fenster für überwachte Ausdrücke aufrufen. Dort fügst du einen neuen hinzu und benutzt dabei nicht die Property sondern das dahinterliegende Feld, welches die Daten enthält. Für die Caption eines Buttons wäre der gesuchte Ausdruck dann Button1.FCaption. Wenn du nun mit dem Debugger durchstepst, dann siehst du im Fenster immer den aktuellen Wert.

Wie kommt man an diesen Feldnamen?
- Raten: Bei der Property Caption lautet der Feldname vermutlich FCaption. Bei Color ist es FColor und so weiter.
- Nachschauen: Man sieht sich im Quellcode die Deklaration der Property an.
Code: Alles auswählen
property Color: TColor read FColor write SetColor stored ColorIsStored default {$ifdef UseCLDefault}clDefault{$else}clWindow{$endif}; property Caption: TCaption read GetText write SetText stored IsCaptionStored;
Bei Caption wird GetText bemüht zum Lesen der Daten. Und die sieht so aus:
Code: Alles auswählen
function TControl.GetText: TCaption;
var
len: Integer;
GetTextMethod: TMethod;
begin
// Check if GetTextBuf is overridden, otherwise we can call RealGetText directly
Assert(Assigned(@Self.GetTextBuf), 'TControl.GetText: GetTextBuf Method is Nil');
GetTextMethod := TMethod(@Self.GetTextBuf);
if GetTextMethod.Code = Pointer(@TControl.GetTextBuf) then begin
Result := RealGetText;
end
else begin
// Bummer, we have to do it the compatible way.
DebugLn('Note: GetTextBuf is overridden for: ', Classname);
len := GetTextLen;
if len = 0 then begin
Result := '';
end
else begin
SetLength(Result, len+1); // make sure there is room for the extra #0
FillChar(Result[1], len, #0);
len := GetTextBuf(@Result[1], len+1);
SetLength(Result, len);
end;
end;
end;
Code: Alles auswählen
function TControl.RealGetText: TCaption;
begin
Result := FCaption;
end;
Warum ist das alles so umständlich und warum kann der Debugger nicht einfach GetText aufrufen?
Das liegt an der Gefahr einen Seiteneffekt auszulösen:
Code: Alles auswählen
function TWatchButton.GetCaption: String;
begin
ReadCount := ReadCount + 1;
Result := FCaption;
end;
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
- 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: Ausgabe von Komponenten-Inhalten
Deswegen muß ich auch in Delphi erst die Option "Funktionsaufrufe erlauben" aktivieren.m.fuchs hat geschrieben: Fr 18. Sep 2020, 12:00
Warum ist das alles so umständlich und warum kann der Debugger nicht einfach GetText aufrufen?
Das liegt an der Gefahr einen Seiteneffekt auszulösen:
Dieser Getter inkrementiert bei jeden Aufruf einen Counter um die Anzahl der Getter-Aufrufe zu loggen. Jedesmal wenn der Debugger die zugehörige Property zugreift, würde das auch passieren. Damit ist der Wert in ReadCount höher als ohne Debuggereinsatz, das Programm verhält sich also mit Debugger anders als ohne. Das sollte man möglichst vermeiden.
Solche Nebeneffekte werden sicher seltener auftreten als das sich der Programmierer den Inhalt von Properties mit Getter Methoden anschauen möchte.
-
- Beiträge: 6899
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Ausgabe von Komponenten-Inhalten
Da hast du recht.

Ich weis nicht mal wie dies geht.

Ich brauche viel ShowMessage() und Writeln().
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2805
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Ausgabe von Komponenten-Inhalten
Das ist dann schon einmal besser als im Visual Studio, dort macht der Debugger das immer.fliegermichl hat geschrieben: Fr 18. Sep 2020, 13:55 Deswegen muß ich auch in Delphi erst die Option "Funktionsaufrufe erlauben" aktivieren.
Ich würde es anders herum sehen. In den meisten Fällen nutzt eine Property nur für den Setter eine Methode. Man will ja häufig den übergebenen Wert verifizieren oder beim Ändern von Werten eine Aktion auslösen. Der Getter zeigt dann einfach nur auf das Feld.fliegermichl hat geschrieben: Fr 18. Sep 2020, 13:55 Solche Nebeneffekte werden sicher seltener auftreten als das sich der Programmierer den Inhalt von Properties mit Getter Methoden anschauen möchte.
Es wird also eher seltener Auftreten, dass man sich tatsächlich die Getter-Methode ansehen muss. Wenn es aber eine gibt, dann sollte man auch reinsehen und nicht den Debugger das Ding automagisch auswerten lassen.
Ist wie beim Experimentieren. Wenn die Messwerte meines Experiments nicht den Erwartungen entsprechen, sollte ich erst einmal prüfen ob ich richtig messe.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2805
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Ausgabe von Komponenten-Inhalten
Das stimmt, der Einsatz eines Debuggers zeigt einem häufig dass irgendwo ein Unit-Test vergessen wurde.

Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de