Erweitertes Code-Editor-Markup, Call-Stack-UI und Multithreading-Debugging-Tools – in einem neuen Plugin für RAD Studio, das jetzt kostenlos erhältlich ist.
Wir freuen uns sehr, heute eine neue IDE-Erweiterung für RAD Studio 10.4.1 ankündigen zu können, die vom gleichen Autor wie die beliebten Plugins Bookmarks und Navigator, Parnassus, erstellt wurde. Wenn Sie dies lesen, ist sie bereits in GetIt für jeden mit Update-Abonnement verfügbar: Öffnen Sie einfach GetIt, gehen Sie zum Abschnitt IDE-Plugins und installieren Sie den ‚Parallel Debugger‘. Er erfordert Delphi oder C++Builder 10.4.1 oder neuer.
Was ist das?
- Ein Werkzeug zum Debuggen von Multithreading-Anwendungen
- …und es hilft auch beim Debuggen traditioneller Singlethreading-Anwendungen!
Etwas für jeden. Lesen Sie weiter für mehr!
Table of Contents
Das Problem
Wenn Sie mehr als einen Thread in Ihrer Anwendung haben, wollten Sie wahrscheinlich schon einmal die Thread-Interaktion debuggen. Eine herkömmliche IDE betrachtet eine debuggte Anwendung zwar in einer Threads-Ansicht mit mehreren Threads, behandelt die Anwendung aber so, als hätte sie nur einen einzigen Thread: Sie sehen nur einen Aufrufstapel, und die Lauf/Pause/Schritt-Steuerungen gelten für den gesamten Prozess. Das lässt Sie, einen Entwickler, der Ihre App debuggen muss, mit Fragen zurück wie:
- Wie kann ich sehen, ob mehrere Threads gleichzeitig im selben Code laufen?
- Wie sehe ich, was alle meine Threads zu einem bestimmten Zeitpunkt tun?
- Wie kann ich eine Methode in nur einem Thread durchlaufen?
D.h. wie debugge ich einen Thread, ohne dass andere Threads laufen und Code ausführen, den ich nicht haben will, oder Breakpoints treffen, usw.? - Wie viel CPU wird von jedem meiner Threads verwendet? Sind sie effizient?
Und vielleicht noch andere Fragen oder Wünsche, auch zum Debuggen nur in einem einzelnen Thread, wie:
- Ich wünschte, es wäre einfach, alle Methoden im Aufrufstapel in meinem Code hervorgehoben zu sehen
- Ich wünschte, ich könnte einen Haltepunkt einfach nur auf einen bestimmten Thread anwenden
- Ich wünschte, das Editor-Markup, das die aktuelle Code-Zeile anzeigt, sähe ein bisschen deutlicher aus
- Ich wünschte, ich würde beim Anhalten des Prozesses nicht in die CPU-Ansicht wechseln, sondern nur meinen eigenen Quellcode sehen
Jede dieser Fragen wird von diesem neuen Plugin beantwortet.
Schauen wir uns seine Funktionen an. Im nächsten Abschnitt erfahren Sie mehr über die Ansicht „Parallele Threads“ und parallele Aufrufstapel, die Ausführung pro Thread und Stepping, die Ansicht „Prozess“, das neue Editor-Markup mit Threads und Aufrufstapeln im Editor, das Setzen der Thread-Affinität eines Haltepunkts, das Verschieben der aktuellen Ausführung, das neue Thread-Hauptmenü und vieles mehr…
Die Ansicht „Parallele Threads
Ansicht > Debug-Fenster > Parallele Threads
In diesem Fenster werden alle Threads des Prozesses in horizontaler Reihenfolge aufgelistet. Wenn Ihre App unter Windows läuft, hat jeder Thread ein Diagramm, das seine CPU-Auslastung anzeigt.
Wenn die App pausiert wird, zeigt jeder Thread seinen Aufrufstapel an.
- Jedem Thread wird eine eindeutige Farbe zugewiesen, beginnend mit einem mittleren Blau für den Hauptthread der Anwendung. Diese Farbe wird als visuelle Hilfe verwendet, um den Thread überall zu identifizieren.
- Thread-Namen werden angezeigt. Selbst wenn Sie Ihren Hauptthread nicht benennen, ist Parallel Debugger intelligent genug, um ihn zu erkennen.
- Der aktuelle Thread ist fett gedruckt und wird von einem dünnen Rand in seiner Farbe umgeben. Doppelklicken Sie auf den Titel eines Threads (seinen Namen), um ihn zum aktuellen Thread zu machen.
- Aufrufstapel-Einträge ohne Quellcode – d. h., sie sind ohne Verwendung der CPU-Ansicht nicht debuggingfähig – sind standardmäßig eingeklappt. Sie können diese ausklappen (oder ausschalten, um einen traditionellen Aufrufstapel anzuzeigen).
Wenn der Prozess angehalten wird, zeigt der Debugger immer den obersten debuggbaren Aufrufstack-Eintrag an. Das heißt, er zeigt vielleicht nicht den obersten Eintrag im Aufrufstapel, wie es die IDE traditionell tut, aber er zeigt den Quellcode von Ihnen, der ihn aufruft. Die Idee hier ist, das zu debuggen, worüber Sie die Kontrolle haben – zeigen Sie immer den Quellcode.
Die Schaltfläche ganz links in jeder Thread-Symbolleiste pausiert den gesamten Prozess und macht diesen Thread zum aktuellen Thread. Sie heißt ‚den Prozess in diesem Thread anhalten‘. Mit der Schaltfläche ganz rechts können Sie die Reihenfolge der angezeigten Threads ändern, indem Sie Threads nach links oder neben einen anderen angehefteten Thread anheften. Dies ist nützlich, wenn Sie viele Threads in Ihrer App haben und die, an denen Sie interessiert sind, in einer Gruppe zusammenfassen möchten. Wenn ein angehefteter Thread einen Namen hat, bleibt die Anheftung über Prozessneustarts hinweg bestehen: Wenn Sie Ihre App beenden und neu starten, werden die gleichen Threads angeheftet.
Ausführen oder Steppen eines einzelnen Threads
Die verbleibenden Schaltflächen der Symbolleiste sind für die Thread-Ausführungssteuerung.
Die normalen IDE-Steuerelemente „run“, „step over“, „step into“ usw. sind auf Prozessebene angesiedelt, d. h. sie lassen den gesamten Prozess laufen, wecken alle Threads auf und Sie hoffen einfach, dass nichts weiter passiert, bis die „step over“-Operation in dem Thread, den Sie betrachten, abgeschlossen ist. In der Praxis kann viel passieren – Ausnahmen, Haltepunkte usw. – und natürlich wollen Sie manchmal einfach nur sicherstellen, dass andere Threads nicht laufen, während Sie einen einzelnen Thread debuggen.
- Nur diesen Thread laufen lassen, alle anderen Threads pausieren lassen
- Diesen Thread pausiert halten, aber alle anderen Threads laufen lassen
- Schritt in eine Methode, nur in diesem Thread
- Schritt über eine Codezeile, nur in diesem Thread. Dies erlaubt nur diesem Thread zu laufen und zu schreiten; keine anderen Threads dürfen zur gleichen Zeit laufen
- Ausführen bis zur Rückkehr der Methode, nur für diesen Thread
Um diese zu verwenden, vergewissern Sie sich, dass das Thema, an dem Sie interessiert sind, das aktuelle Thema ist, indem Sie auf seinen Titel oder Namen doppelklicken. Sie werden sehen, dass der Titel fett gezeichnet ist.
Jede dieser Funktionen hat einen Tastaturkurzbefehl, d. h. Sie können die Schritte (usw.) über die Tastatur ausführen, nicht nur durch Anklicken einer Schaltfläche mit der Maus. Die Tastaturkürzel sind im Menü „Thread“ sichtbar, das Menüpunkte für den aktuellen Thread enthält (siehe unten).
Die Ablaufsteuerung pro Thread ist eine der leistungsstärksten Funktionen im Parallel Debugger.
Editor-Integration
Eine wichtige Aufgabe beim Verstehen der Vorgänge in einer Multithread-Anwendung ist es, zu wissen, wann mehrere Threads im selben Codebereich ausgeführt werden. Der Parallel Debugger macht dies durch das Hinzufügen von Markierungen im Editor für den vollständigen Aufrufstapel jedes Threads deutlich. Diese werden über „Tags“, kleine farbige Markierungen auf der rechten Seite des Editors, angezeigt.
Der oberste Call-Stack-Eintrag – also derjenige, an dem der Thread „jetzt“ ausgeführt wird – wird mit einem einfarbigen Tag in der Thread-Farbe markiert. Andere Aufrufstapel-Einträge für denselben Thread sind in einer verblassten Version der Thread-Farbe dargestellt (wobei der Thread immer noch mit einem durchgehenden Kreis im Tag markiert ist).
So können Sie Ihren Code schnell lesen und wissen: „Thread X wird irgendwo in dieser Codezeile ausgeführt“ und „Thread Y und Thread Z befinden sich beide gerade in der gleichen Methode“. Sie sehen sogar, wo sich die Threads genau befinden. In diesem Screenshot ist der aktuelle Thread der blaue, und ein zweiter Thread (hellrot) wird mit seinem aktuellen Ausführungspunkt innerhalb von IsPrime() ausgeführt, aber der Aufruf von IsPrime hat die Zeile über dem Ausführungspunkt des aktuellen Threads hervorgehoben.
Verschieben der Ausführung
Vor der Installation des Plugins hat die IDE den Ausführungspunkt des aktuellen Threads mit einem kleinen blauen Pfeil angezeigt. Dieser wird nun durch einen großen Chevron auf der linken Seite des Code-Editors ersetzt.
Sie können die Position des Ausführungspunkts ändern, d. h. die Stelle, an der der Thread das nächste Mal ausgeführt wird, wenn Sie auf „Run“ oder „Step“ klicken, indem Sie einfach auf diese Markierung klicken und sie verschieben.
Haltepunkt-Thread-Affinität
Standardmäßig gelten Haltepunkte für alle Threads. Vor der Installation des Plugins wurden Haltepunkte mit einem roten Punkt gezeichnet, aber mit dem Parallelen Debugger werden Threads Farben gegeben, und Rot bedeutet den roten Thread. Haltepunkte, die für alle Threads gelten, werden jetzt als ein mehrfarbiges Rad gezeichnet.
Um einen Haltepunkt nur für einen bestimmten Thread gelten zu lassen, klicken Sie mit der rechten Maustaste auf den Haltepunkt. Im neuen Haltepunktmenü können Sie einen Thread auswählen, für den der Haltepunkt gelten soll.
Hier gilt dieser Haltepunkt nur für den grünen Thread.
Die Prozessansicht
Ansicht > Debug-Fenster > Prozess
Dieses Fenster zeigt Informationen über den Prozess als Ganzes an. Es zeigt die CPU-Auslastung auf Prozessebene (wiederum aufgeteilt in Kernel- und Usermode), den Prozesstyp (z. B. Wow64) und hat Schaltflächen für Ausführen/Pause/Zurücksetzen usw. Diese sind auf Prozessebene, d.h. sie bieten die gleiche Funktionalität wie die IDE-eigene Ausführen-Symbolleiste.
Sie können auch eine Liste von Threads sehen, indem Sie auf die Schaltfläche am unteren Rand klicken, als schnelle Möglichkeit, den aktuellen Thread auszuwählen (da das horizontale Scrollen in der Threads-Ansicht länger dauern kann, wenn Sie viele Threads haben).
Das Thread-Hauptmenü
Die IDE verfügt jetzt über ein Thread-Menü, das sich rechts neben dem Ausführen-Menü befindet. Dieses bietet ein Menü für die meisten der direkten Operationen, die Sie für einen Thread durchführen können. Es lässt Sie den Thread von Interesse einstellen (d. h. den aktuellen Thread, wenn der Prozess angehalten ist, oder den Thread, der beim nächsten Anhalten zum aktuellen Thread werden soll), und für den aktuellen Thread gibt es Menüpunkte für die Thread-Laufkontrolle. Auf diesen Menüeinträgen sind Verknüpfungen zu sehen.
Außerdem werden alle Threads in der App aufgelistet, und für jeden wird die Ablaufsteuerung und das Anheften angezeigt, also praktisch die gleichen Funktionen wie in der Ansicht „Parallele Threads“.
Merkmal Level
Schließlich steuert der oberste Menüpunkt die Funktionsstufe des Parallel-Debuggers: was er tut, wenn Ihre App läuft. Die niedrigste Ebene dient nur zum Verfolgen der CPU-Auslastung: Verwenden Sie dies, wenn Sie den parallelen Debugger installieren möchten, ihn aber derzeit nicht aktiv für diese App verwenden wollen. Die nächsten beiden Stufen steuern, wie tief der Debugger Thread-Aufrufstapel verfolgt.
Verwenden Sie dies, wenn Sie Dutzende oder Hunderte von Threads haben. In dieser Situation sind Sie wahrscheinlich nur an einer Teilmenge von Threads interessiert. Wenn Sie die Funktionsstufe auf „Nur ausgewählte Aufrufstapel“ einstellen, verfolgt der parallele Debugger standardmäßig nur die Aufrufstapel für den Hauptthread, die angehefteten Threads und den aktuellen Thread. Sie können jederzeit den Aufrufstapel für jeden Thread abrufen, indem Sie auf eine Schaltfläche klicken, die über dem Aufrufstapelbereich in der Threads-Ansicht angezeigt wird.
Unterstützte Plattformen
Der Parallel Debugger hat die volle Funktionalität beim lokalen Debuggen von Anwendungen unter Windows.
Auf anderen Plattformen oder beim Remote-Debugging hängt die Funktionalität davon ab, was der Debugger unterstützt. Die CPU-Nutzung wird nur für lokale (nicht entfernt debuggende) Windows-Anwendungen unterstützt. Per-Thread-Stepping oder -Lauf wird nur auf Plattformen funktionieren, die Thread-Freezing unterstützen. Es gibt ein bekanntes Problem für C++ Win64, bei dem Aufrufstapel nicht ausgewertet werden können: dies wird in einer kommenden C++Builder-Version behoben.
Einer mit Bookmarks begonnenen Parnassus-Tradition folgend, behebt der Parallel Debugger tatsächlich einen Fehler! (RSP-29768.)
Generell gilt: Wenn Sie Windows verwenden, hat der Debugger volle Funktionalität.
Das Plugin unterstützt RAD Studio 10.4.1 (und neuer, wenn 10.4.2 herauskommt.)
Den parallelen Debugger erhalten
Der Parallele Debugger ist jetzt in GetIt!
Dank Embarcadero stellt Parnassus den Debugger jedem RAD Studio-Kunden mit aktivem Update-Abonnement kostenlos zur Verfügung. Öffnen Sie GetIt, gehen Sie zur Kategorie IDE-Plugins und klicken Sie auf Installieren.
Sowohl Parnassus als auch Embarcadero hoffen, dass Sie diese Erweiterung als großartige Ergänzung zu Ihrer IDE empfinden werden.
Persönlich möchte ich mich bei Embarcadero dafür bedanken, dass sie sich für das Plugin interessiert haben und es zu GetIt hinzufügen wollten, und bei all meinen Beta-Testern, die seit August verschiedene Versionen dieses Plugins von langsam steigender Qualität verwendet haben. Herzlichen Dank an alle!