![]() |
Grundsatzfrage Debuggen mit aktiven Threads
Ich würde gern so eine Art Live-Debugging realisieren.
Dazu übertrage ich bestimmte Daten meiner Anwendung über TCP an ein lauschendes Programm. Das funktioniert soweit. Jetzt möchte ich das auch während dem Debuggen nutzen, bin aber nicht sicher, ob und wie das geht. Kleines und verkürztes Gedankenexperiment: In TForm.OnCreate läuft ein Zähler I (globale Variable) von 0 bis MaxInt hoch, mehr nicht. Zusätzlich gibt es 3 Threads. TThreadBeep: Beept jede Sekunde TThreadC: Zählt einen eigenen Counter hoch und versendet den über TCP TThreadI: Übernimmt (synchronisiert?) den Wert aus der obigen I-Schleife und versendet den. Das sollte soweit funktionieren. Während der Zähler hochzählt piepst die Anwendung jede Sekunde und das lauschende Programm erhält neue Werte für C und I. Ein Breakpoint in der I-Schleife hält aber auch die 3 Threads an. Gibt es eine Möglichkeit, diese weiter laufen zu lassen? Ich möchte also weiter die Beeps jede Sekunde, den hochzählenden Counter C und "den aktuellen Wert aus I". Die Threads Beep und C sollen also unbeeindruckt weiter laufen und I soll während des Debuggens immer weiter den aktuellen Wert verschicken. Erst wenn ich mit F8 schrittweise weiter debugge, müsste also im beobachtenden Programm dann beim jeweils nächsten Schleifendurchlauf der nächste I-Wert angezeigt werden. Lässt sich so etwas realisieren? Ich kenne zwar die Threads im Debugfenster, weiß aber (noch) nicht, wie und wie weit man damit umgehen kann. EDIT: Wenn das so nicht machbar ist, müsste man vermutlich einen Thread in den OTA´s verankern, aber das wäre dann mit Kanonen auf Spatzen... |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Andersrum geht es definitiv.
Also man kann bestimmte Threads "blockieren", dann arbeiten sie nicht weiter, während man mit F7/F8/F9 den aktuellen/ausgewählten Thread debuggt. Über die Open Tools API kannst bestimmt kurz nach dem Anhalten andere Threads gleich wieder starten, aber ja, im Prinzip könnte Emba in Delphi bestimmt auch direkt zum "blockieren" noch ein "ignorieren/weiterarbeiten" einbauen, also nicht immer gleich alle Threads anhalten, wenn angehalten wird. > Delphi hat ja beim "Weiterdebuggen" schon drin, dass nicht alle Threads wieder fortgesetzt werden, fehlt halt nur beim "Anhalten" dass nicht Alle pausieht werden. Oder eben selbst Debugger-Anhalte-Event in der OTA suchen (und hoffen da gibt es was Passendes) und mit ![]() Ich hatte mir nur manchmal das Andere gewünscht, also dass beim Debuggen (F7/F8) die Timer blockiert/verzögert werden. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Zitat:
Denkbar währe I durch einen Record mit Zuweisungsoperatoren (in beide Richtungen) für Integer zu ersetzen. Der Record müsste auch eine CriticalSection enthalten, die beim Zugriff auf die interne Variable verwendet werden. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Wegen einem winzigen Integer gleich mit Kanonen auf Spatzen?
Sowas kann direkt die CPU sicher (atomar) schreiben und auslesen kann man es direkt ganz normal. ![]() ![]() |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Danke Euch schon mal.
Bei meiner Realanwendung laufen die Threads ja wieder los, wenn ich nach einem Breakpoint das Programm mit F9 weiter laufen lasse. Wenn der nächste Breakpoint vielleicht nach 2-3 Sekunden erreicht würde, würde das vermutlich reichen, um einen neuen Datenbestand raus zu schicken. Die Frage ist, wie sich das "Weiterlaufen der Anwendung" darstellt, wenn die Zeitspanne durch F8 nur einige Millisekunden beträgt. Ob in der Zeit mal ein Thread aktiv werden kann? Vermutlich wohl nicht. Vermutlich wäre notwendig, wie von Himitsu vorgeschlagen, dass man der IDE auftragen können müsste, bestimmte Threads nicht zu pausieren... Dann werde ich mein Vorhaben so nicht umsetzen können... Alternative wäre ein Debug-Viewer (ähnlich dem für TStringList), der dann die Daten dann direkt innerhalb der IDE darstellt. Muss ich mir mal überlegen, ob ich den Aufwand betreiben will. Vom Händling her ist das ja auch nicht so optimal. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Hallo,
schon mal das neue IDE Plugin von Parnassus zum Multithreaded debuggen angeschaut? Findet sich in GetIt package manager, könnte das evtl. können. Einziger Nachteil: es hat wohl noch ein paar Bugs die unschöne Fehlermeldungen beim Schließen von Projekten oder so erzeugen. Entwickler hat aber versprochen diese zu fixen. Ist halt noch V1.00. Grüße TurboMagic |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Vielen Dank.
Das sieht ganz gut aus, ist aber für mich vielleicht etwas zu komplex. Ich werde doch erst mal schauen, ob ich das als internen Objekt-Viewer umsetzen kann. Dann wäre keine Thread-Kontrolle notwendig und keine Datenübertragung über TCP. Vielleicht ist das (wenn die benötigten Threads nicht einfach weiter laufen können) dann doch die geschicktere Lösung... Ich gebe bescheid, ob ich das so umsetzen kann... |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Alternativ ohne Thread, in deinem Code eine SendeFunktion überall einfügen/aufrufen, da kannst dann mit F8 drüber und deine Daten raussenden.
|
AW: Grundsatzfrage Debuggen mit aktiven Threads
Ja, aber das ist dann unpraktisch.
Dann muss man zuvor genau sagen, an welchen Stellen man den Datenblock einsehen möchte. Das benötigte mehrfache Korrekturen im Code und mehrfaches Debuggen und genau das will ich vermeiden. Ich möchte also bei jedem Debug-Schritt eine aktualisierte visuelle Aufbereitung der Daten sehen. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Dafür eignen sich Tools wie TMS Logging:
![]() Damit kannst du nebenbei eine Webseite aufmachen und die Logs strukturiert einsehen. Du kannst die Daten aber auch in einem eigenen IDE Plugin abrufen usw. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Liste der Anhänge anzeigen (Anzahl: 1)
Ich brauche eine recht komplexe Darstellung verschachtelter Interfaces incl. Steuerzeichen usw. und daher ein eigenes Formular (im Bild mal einen ersten Ansatz).
Bin gerade dabei, mir mal ein Plugin aufzubauen. Einen einfachen Visualizer hatte ich schon mal umgesetzt: ![]() Das wird dann jetzt die Formular-Variante. Die Formular-Umsetzung selbst wird dann aber ähnlich werden, wie die ursprünglich geplante. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Liste der Anhänge anzeigen (Anzahl: 3)
Ich bin dabei, den Viewer für TStrings für mich umzubauen, komme aber damit nicht klar... :-(
Vielleicht kann mir jemand helfen? Ich zeige das mal anhand von Screenshots.. 1) SpyDetect ist eine Interfacevariable, die ich einsehen möchte. Mit der Lupe kann ich schon mal ein Formular öffnen. 2) Die Werte, die der Viewer erhält sieht man hier. 3) Hier möchte ich die Objekt- oder Interface-Instanz erhalten und direkt alle deren Eigenschaften auslesen. Also irgendwie so etwas wie MyIntf := IDetect(ResultAddr) oder MyObj := TDetect(ResultAddr) Gibt es da eine Möglichkeit. Das ist für mich alles nicht so ganz eingängig... :| |
AW: Grundsatzfrage Debuggen mit aktiven Threads
*kleiner Push*
Ich habe mich jetzt nochmal etwas mehr damit beschäftigt. Da der Viewer für TStringList auch nicht einfach das Objekt referenzieren kann, gehe ich davon aus, dass es dafür generell keine Möglichkeit gibt. Insofern muss ich wohl den Datenblock wohl auch in eine Datei schreiben und im Viewer wieder aus der Txt generieren und dann diese Datenkopie darstellen.
Delphi-Quellcode:
// Lösung aus dem StringList-Viewer
Txt := GetText; if Length(Txt) < 4096 then StringTextView.Text := FromDbgStrToText(Txt) else begin TempFile := TPath.GetTempFileName; try GetSaveToFile(TempFile); StringTextView.Lines.LoadFromFile(TempFile); finally DeleteFile(TempFile); end; end; Im Grunde also auch wieder so ähnlich, wie ich es über die Socket-Variante gelöst hatte. Ist das so richtig? |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Naja, du kannst es ja manuell machen.
Pointer/Referenz der StringList, da x Bytes offset zum FList und dann kannst dich da mit ReadProcessMemory durch das Array der Strings kämpfen. Falls der Compiler "ungenutzte" Variablen weggelassen hat, müsstest du vorher noch die RTTI suchen und dir da den "aktuellen" Offset rausholen. Die TClass und somit die RTTI sind als erstes in einer ObjektInstanz verlinkt. Wenn es eine eigene Komponente ist, dann könnte man statt GetMem vom Speichermanager (Delphi oder Windows) eine MemoryMappedFile nutzen, auf welche man vom Debugger aus zugreifen könnte. (muß man dann nicht direkt im fremden Speicher rumsuchen) |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Danke Euch.
Ich habe es jetzt über eine Textdatei gelöst. Hier ein kleiner, grundsätzlicher Einblick: ![]() Wenn Interesse besteht, zeige ich gern mehr wenn es fertig ist und stelle es auch gern zur Verfügung. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Liste der Anhänge anzeigen (Anzahl: 3)
Das Styling komplett ausschalten habe ich nicht geschafft.
Ich weiß ja auch nicht, welche Auswirkungen irgendwelche Eingriffe auf die IDE haben können... Aber Umschalten auf den Style "Windows" scheint gut zu helfen und keine Probleme zu machen. Zumindest werde ich jetzt mal damit weiter arbeiten.
Delphi-Quellcode:
function TDebuggeruoDetectVisualizer.Show(const Expression, TypeName, EvalResult: string;
Suggestedleft, SuggestedTop: Integer): IOTADebuggerVisualizerExternalViewerUpdater; var AForm: TCustomForm; AFrame: TuoDetectViewerFrame; VisDockForm: INTACustomDockableForm; begin VisDockForm := TuoDetectVisualizerForm.Create(Expression) as INTACustomDockableForm; AForm := (BorlandIDEServices as INTAServices).CreateDockableForm(VisDockForm); AForm.Left := Suggestedleft; AForm.Top := SuggestedTop; (VisDockForm as IFrameFormHelper).SetForm(AForm); AFrame := (VisDockForm as IFrameFormHelper).GetFrame as TuoDetectViewerFrame; AFrame.GeTuoDetect(Expression, TypeName, EvalResult); Result := AFrame as IOTADebuggerVisualizerExternalViewerUpdater; if Assigned(TStyleManager.ActiveStyle) and (TStyleManager.ActiveStyle.Name <> 'Windows') then begin TStyleManager.TrySetStyle('Windows'); // <<<=============== end; end; EDIT 1: - Es hat doch Auswirkungen. Siehe zweiten Screenshot. - Kann ich für ein Formular das Skinning einfach deaktivieren (ohne etwas am TStyleManager zu machen)? EDIT 2: - mit
Delphi-Quellcode:
im obigen Codeauszug scheint es zu funktionieren
AForm.StyleName := 'Windows';
- anbei noch ein paar Sekunden Video, was ich damit mache (Verschachtelungen darstellen) - hätte ich schonmal eher machen sollen, hätte mir wohl einigen Ärger erspart |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Weil ich gerade selbst so begeistert bin, hier mal ein kurzer Zwischenstand:
![]() Das taugt so für das Debuggen komplexer Daten sehr gut. Die Positionen der Überwachungsformulare werden Dateinamenbezogen in einer Ini abgelegt, so dass die Formulare immer an der letzten Stelle neu geöffnet werden. Ist so richtig nützlich und fast perfekt. :-) Wenn es jemand mal braucht, stelle ich es gern bereit (die Datendarstellung selbst muss man dann natürlich auf den eigenen Bedarf anpassen - die Datenübergabe erfolgt über eine Textdatei)... |
AW: Grundsatzfrage Debuggen mit aktiven Threads
hab'sch gestern entdeckt (noch nicht ausprobiert)
![]() Ist zwar scheinbar kein Start/Stop drin, aber mehrfache Stacktraces und so. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Danke, da traue ich mich erst mal noch nicht ran.
Vielleicht gibt es ja mal irgendwann noch ein paar Demos dazu... |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Witzig war das Verschieben des Stackpointers via Drag&Drop links in der Editorleiste. (ich vergesse eh immer den Shortcut für :roll:)
Da man eh zuiel Platz auf dem Monitor hat, ist so der Platz bissl genutzt. ![]() Auf seiner Webseite hast auch paar Bilder/Animationen und vielleicht findest auch was in seinem Blog ... klein bissl was zur OTA. |
AW: Grundsatzfrage Debuggen mit aktiven Threads
Wow, das Tool ist super. Das hatte ich bisher nicht gesehen (gibt es ja auch erst seit Ende 2020). Gerade die Threadaffinität von Haltepunkten hat mir schon immer wieder massiv gefehlt.
Mehr dazu steht ja mit Screenshots in der Ankündigung: ![]() Ich habe das gerade einmal ausprobiert, damit ist das Debuggen von Threads wirklich deutlich einfacher. Und die Benutzung ist absolut einfach und intuitiv. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz