Debuggerdatenmodell C++-Übersicht
Dieses Thema bietet eine Übersicht über die Verwendung von Debuggerdatenmodell-C++-Schnittstellen zum Erweitern und Anpassen der Funktionen des Debuggers.
Dieses Thema ist Teil einer Reihe, in der die Schnittstellen beschrieben werden, auf die über C++ zugegriffen werden kann, wie sie zum Erstellen einer C++-basierten Debuggererweiterung verwendet werden und wie andere Datenmodellkonstrukte (z. B. JavaScript oder NatVis) aus einer C++-Datenmodellerweiterung verwendet werden.
Debuggerdatenmodell C++-Übersicht
Debuggerdatenmodell-C++-Schnittstellen
Debuggerdatenmodell C++-Objekte
Debuggerdatenmodell C++-Zusätzliche Schnittstellen
Debuggerdatenmodell-C++-Konzepte
Debuggerdatenmodell C++-Skripterstellung
Übersicht über die Debuggerdatenmodell-C++-Schnittstelle
Das Debuggerdatenmodell ist ein erweiterbares Objektmodell, das von zentraler Bedeutung dafür ist, wie neue Debuggererweiterungen (einschließlich der in JavaScript, NatVis und C++) vom Debugger bereitgestellte Informationen nutzen und Informationen erzeugen, auf die vom Debugger und von anderen Erweiterungen zugegriffen werden kann. Konstrukte, die in die Datenmodell-APIs geschrieben werden, sind im neueren Ausdrucksauswertungs-Evaluator des Debuggers sowie aus JavaScript-Erweiterungen oder C++-Erweiterungen verfügbar.
Um die Ziele des Debuggerdatenmodells zu veranschaulichen, betrachten Sie diesen herkömmlichen Debuggerbefehl.
0: kd> !process 0 0
PROCESS ffffe0007e6a7780
SessionId: 1 Cid: 0f68 Peb: 7ff7cfe7a000 ParentCid: 0f34
DirBase: 1f7fb9000 ObjectTable: ffffc001cec82780 HandleCount: 34.
Image: echoapp.exe
...
Der Debuggerbefehl verwendet eine binäre Maske und stellt nur Textausgabe auf nicht standardmäßige Weise bereit. Die Textausgabe kann nur schwer verarbeitet, formatiert oder erweitert werden, und das Layout ist spezifisch für diesen Befehl.
Kontrastieren Sie dies mit dem Befehl Debuggerdatenmodell dx (Debuggerobjektmodellausdruck anzeigen).
dx @$cursession.Processes.Where(p => p.Threads.Count() > 5)
Dieser Befehl verwendet ein Standarddatenmodell, das auf einheitliche Weise auffindbar, erweiterbar und zusammensetzbar ist.
Durch logisches Benennen von Abständen und Erweitern auf bestimmte Objekte können Debuggererweiterungsfunktionen ermittelt werden.
Tipp
Da die Datenmodell-C++-Objektschnittstellen sehr ausführlich sein können, wird empfohlen, eine vollständige C++-Hilfsbibliothek für das Datenmodell zu implementieren, die eine vollständige C++-Ausnahme verwendet, und das Programmierparadigma für Vorlagen wird empfohlen. Weitere Informationen finden Sie weiter unten in diesem Thema unter Verwenden der DbgModelClientEx-Bibliothek .
Das Datenmodell ist die Art und Weise, wie WinDbg die meisten Dinge zeigt. Viele Elemente in der neuen Benutzeroberfläche können abgefragt, erweitert oder skriptiert werden, da sie vom Datenmodell unterstützt werden. Weitere Informationen finden Sie unter WinDbg – Datenmodell.
Architekturansicht des Datenmodells
Das folgende Diagramm fasst die wichtigsten Elemente der Debuggerdatenmodellarchitektur zusammen.
- Auf der linken Seite werden UI-Elemente angezeigt, die den Zugriff auf die Objekte ermöglichen und funktionen wie LINQ-Abfragen unterstützen.
- Auf der rechten Seite des Diagramms befinden sich Komponenten, die Daten für das Debuggerdatenmodell bereitstellen. Dies umfasst benutzerdefinierte NatVis-, JavaScript- und C++-Debugger-Datenmodellerweiterungen.
Objektmodell
Im Mittelpunkt des Debuggerdatenmodells steht eine einheitliche Objektdarstellung, bei der alles ein instance der IModelObject-Schnittstelle ist. Ein solches Objekt kann zwar einen intrinsischen (z. B. einen ganzzahligen Wert) oder eine andere Datenmodellschnittstelle darstellen, stellt jedoch häufig ein dynamisches Objekt dar – ein Wörterbuch mit Schlüssel-Wert-/Metadatentupeln und eine Reihe von Konzepten, die abstrakte Verhaltensweisen beschreiben.
Dieses Diagramm zeigt, wie das IModelObject Schlüsselspeicher verwendet, um Werte zu enthalten, die ein Anbieter erstellen, registrieren und bearbeiten kann.
- Es wird ein Anbieter angezeigt, der Informationen zum Objektmodell bereitstellt.
- Auf der linken Seite wird das IModelObject angezeigt, d. h. das allgemeine Objektmodell, das zum Bearbeiten von Objekten verwendet wird.
- In der Mitte befindet sich der Schlüsselspeicher , der zum Speichern und Zugreifen auf Werte verwendet wird.
- Unten werden Konzepte angezeigt, die Objekte mit Funktionalität unterstützen, z. B. die Möglichkeit, in eine anzeigebare Zeichenfolge zu konvertieren oder indiziert zu werden.
Das Datenmodell: Eine Consumeransicht
Das nächste Diagramm zeigt eine Consumeransicht des Datenmodells. Im Beispiel wird der Befehl dx (Debugger-Objektmodellausdruck anzeigen) verwendet, um Informationen abzufragen.
- Der Dx-Befehl kommuniziert über ein Serialisierer mit der Objektaufzählungsschnittstelle.
- IDebugHost*-Objekte werden verwendet, um Informationen aus der Debugger-Engine zu sammeln.
- Ausdrucks- und semantische Auswertungen werden verwendet, um die Anforderung an die Debugger-Engine zu senden.
Das Datenmodell: Eine Produceransicht
Dieses Diagramm zeigt eine Produceransicht des Datenmodells.
- Auf der linken Seite wird ein NatVis-Anbieter angezeigt, der XML nutzt, das zusätzliche Funktionen definiert.
- Ein JavaScript-Anbieter kann dynamische Anbieterkonzepte nutzen, um Informationen in Echtzeit zu bearbeiten.
- Unten wird ein systemeigener Codeanbieter angezeigt, der auch zusätzliche Funktionen definieren kann.
Datenmodell-Manager
Dieses Diagramm zeigt die zentrale Rolle, die der Datenmodell-Manager bei der Verwaltung von Objekten spielt.
- Der Datenmodell-Manager fungiert als zentrale Registrierungsstelle für alle Objekte.
- Auf der linken Seite wird gezeigt, wie Standarddebuggerelemente wie Sitzungen und Prozesse registriert werden.
- Der Namespaceblock zeigt die zentrale Registrierungsliste an.
- Die rechte Seite des Diagramms zeigt zwei Anbieter, einen für NatVis oben und eine C/C++-Erweiterung unten.
Zusammenfassung der Debuggerdatenmodellschnittstellen
Es gibt eine Vielzahl von C++-Schnittstellen, die verschiedene Teile des Datenmodells umfassen. Um diese Schnittstellen konsistent und einfach anzugehen, werden sie nach allgemeinen Kategorien aufgeschlüsselt. Hier Standard Bereiche:
Das allgemeine Objektmodell
Der erste und wichtigste Satz von Schnittstellen definieren, wie Sie Zugriff auf das Kerndatenmodell erhalten und wie Sie auf Objekte zugreifen und diese bearbeiten. IModelObject ist die Schnittstelle, die jedes Objekt im Datenmodell darstellt (ähnlich wie das C#-Objekt). Dies ist die Standard Schnittstelle, die sowohl für Verbraucher als auch für Produzenten von Interesse ist, zum Datenmodell. Die anderen Schnittstellen sind Mechanismen für den Zugriff auf verschiedene Aspekte von Objekten. Für diese Kategorie sind die folgenden Schnittstellen definiert:
Brücken zwischen DbgEng und dem Datenmodell
Hauptschnittstellen
IModelKeyReference / IModelKeyReference2
Konzeptschnittstellen
IDynamicConceptProviderConcept
Verwaltung von Datenmodellen und Erweiterbarkeit
Der Datenmodell-Manager ist die Kernkomponente, die verwaltet, wie die gesamte Erweiterbarkeit erfolgt. Es ist das zentrale Repository einer Gruppe von Tabellen, die sowohl native Typen Erweiterungspunkten als auch synthetische Konstrukte Erweiterungspunkten zuordnen. Darüber hinaus ist es die Entität, die für das Boxen von Objekten (Konvertierung von Ordnungswerten oder Zeichenfolgen in IModelObjects) verantwortlich ist.
Für diese Kategorie sind die folgenden Schnittstellen definiert:
Allgemeiner Datenmodell-Manager-Zugriff
IDataModelManager / IDataModelManager2
Skriptverwaltung
IDataModelScriptProviderEnumerator
Zugriff auf das Typsystem und die Speicherplätze des Debuggers
Das zugrunde liegende Typsystem und die Arbeitsspeicherplätze des Debuggers werden ausführlich für Erweiterungen verfügbar gemacht, die verwendet werden können. Für diese Kategorie sind die folgenden Schnittstellen definiert:
Allgemeine Hostschnittstellen (Debugger)
IDebugHostMemory / IDebugHostMemory2
IDebugHostEvaluator / IDebugHostEvaluator2
Host (Debugger) Typ Systemschnittstellen
IDebugHostSymbol / IDebugHostSymbol2
IDebugHostType / IDebugHostType2
IDebugHostBaseClassIDebugHostPublic
Hostunterstützung (Debugger) für Skripterstellung
Erstellen und Verwenden von Skripts
Das Datenmodell hat auch eine allgemeine Vorstellung davon, was ein Skript ist und wie es zu debuggen ist. Es ist durchaus möglich, dass eine Debuggererweiterung kommt und eine allgemeine Brücke zwischen dem Datenmodell und einer anderen dynamischen Sprache (normalerweise eine Skriptumgebung) definiert. Dieser Satz von Schnittstellen ist, wie dies erreicht wird, und wie eine Debugger-Benutzeroberfläche solche Skripts verwenden kann.
Für diese Kategorie sind die folgenden Schnittstellen definiert:
Allgemeine Skriptschnittstellen
IDataModelScriptTemplateEnumerator
Skriptdebuggerschnittstellen
IDataModelScriptDebugStackFrame
IDataModelScriptDebugVariableSetEnumerator
IDataModelScriptDebugBreakpoint
IDataModelScriptDebugBreakpointEnumerator
Verwenden der DbgModelClientEx-Bibliothek
Übersicht
Die Datenmodell-C++-Objektschnittstellen zum Datenmodell können sehr ausführlich zu implementieren sein. Sie ermöglichen zwar die vollständige Bearbeitung des Datenmodells, erfordern jedoch die Implementierung einer Reihe kleiner Schnittstellen, um das Datenmodell zu erweitern (z. B. eine IModelPropertyAccessor-Implementierung für jede hinzugefügte dynamisch abrufbare Eigenschaft). Darüber hinaus fügt das HRESULT-basierte Programmiermodell eine erhebliche Menge an Kesselplattencode hinzu, der für die Fehlerüberprüfung verwendet wird.
Um einige dieser Arbeiten zu minimieren, gibt es eine vollständige C++-Hilfsbibliothek für das Datenmodell, die ein vollständiges C++-Ausnahme- und Vorlagenprogrammierungsparadigma verwendet. Die Verwendung dieser Bibliothek ermöglicht präziseren Code beim Verwenden oder Erweitern des Datenmodells und wird empfohlen.
Es gibt zwei wichtige Namespaces in der Hilfsbibliothek:
Debugger::D ataModel::ClientEx – Hilfsprogramme für die Nutzung des Datenmodells
Debugger::D ataModel::P roviderEx – Hilfsprogramme für die Erweiterung des Datenmodells
Weitere Informationen zur Verwendung der DbgModelClientEx-Bibliothek finden Sie in der Infodatei auf dieser Github-Website:
https://github.com/Microsoft/WinDbg-Libraries/tree/master/DbgModelCppLib
HelloWorld C++-Beispiel
Informationen zur Verwendung der DbgModelClientEx-Bibliothek finden Sie im Data Model HelloWorld C++-Beispiel hier.
https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld
Das Beispiel umfasst Folgendes:
HelloProvider.cpp: Dies ist eine Implementierung einer Anbieterklasse, die der Vorstellung eines Prozesses des Debuggers eine neue Beispieleigenschaft "Hello" hinzufügt.
SimpleIntroExtension.cpp: Dies ist eine einfache Debuggererweiterung, die der Vorstellung eines Prozesses des Debuggers eine neue Beispieleigenschaft "Hello" hinzufügt. Diese Erweiterung wird für die Datenmodell-C++17-Hilfsbibliothek geschrieben. Es ist aufgrund des Volumens (und der Komplexität) von Glue-Code, das erforderlich ist, weit vorzuziehen, Erweiterungen für diese Bibliothek zu schreiben, anstatt den unformatierten COM-ABI.
JavaScript- und COM-Beispiele
Um die verschiedenen Möglichkeiten zum Schreiben einer Debuggererweiterung mit dem Datenmodell besser zu verstehen, stehen hier drei Versionen der Datenmodellerweiterung HelloWorld zur Verfügung:
https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld
JavaScript: Eine in JavaScript geschriebene Version
C++17: Eine Version, die für die C++17-Clientbibliothek des Datenmodells geschrieben wurde
COM: Eine Version, die für die unformatierte COM-ABI geschrieben wurde (nur mit WRL für COM-Hilfsprogramme)
Siehe auch
Debuggerdatenmodell-C++-Schnittstellen
Debuggerdatenmodell C++-Objekte
Debuggerdatenmodell C++-Zusätzliche Schnittstellen