Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieses Thema enthält 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 von C++ zugänglichen Schnittstellen beschrieben werden, wie sie zum Erstellen einer C++-basierten Debuggererweiterung und zur Verwendung anderer Datenmodellkonstrukte (z. B. JavaScript oder NatVis) aus einer C++-Datenmodellerweiterung verwendet werden.
Debuggerdatenmodell-C++-Schnittstellen
Debugger-Datenmodell-C++-Objekte
Zusätzliche Schnittstellen für das Debuggerdatenmodell C++
Debuggerdatenmodell-C++-Konzepte
Debuggerdatenmodell C++-Skripting
Übersicht über die Debugger-Datenmodell-C++-Schnittstelle
Das Debuggerdatenmodell ist ein erweiterbares Objektmodell, das zentral für die Art und Weise ist, in der neue Debuggererweiterungen (einschließlich derer in JavaScript, NatVis und C++) sowohl Informationen vom Debugger nutzen als auch Informationen erzeugen, auf die über den Debugger sowie andere Erweiterungen zugegriffen werden kann. Konstrukte, die in die Datenmodell-APIs geschrieben werden, sind im neueren (dx)-Ausdrucks-Evaluator des Debuggers sowie aus JavaScript-Erweiterungen oder C++-Erweiterungen verfügbar.
Betrachten Sie diesen herkömmlichen Debuggerbefehl, um die Ziele des Debuggerdatenmodells zu veranschaulichen.
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 verwendet, formatiert oder erweitert werden, und das Layout ist für diesen Befehl spezifisch.
Im Gegensatz dazu steht der Befehl "dx (Ausdruck des Debuggerobjektmodells anzeigen)" des Debuggerdatenmodells.
dx @$cursession.Processes.Where(p => p.Threads.Count() > 5)
Dieser Befehl verwendet ein Standarddatenmodell, das auf einheitliche Weise auffindbar, erweiterbar und komponiert werden kann.
Durch logisches Namespacing und die Erweiterung bestimmter Objekte wird die Entdeckung von Debugger-Erweiterungsfunktionen ermöglicht.
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 das komplette C++-Paradigma für Ausnahmebehandlung und Vorlagenprogrammierung verwendet. Weitere Informationen finden Sie unter Verwenden der DbgModelClientEx-Bibliothek weiter unten in diesem Thema.
Das Datenmodell ist die Art und Weise, wie WinDbg die meisten Dinge anzeigt. 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 Zugriff auf die Objekte ermöglichen und diese Funktionalität wie LINQ-Abfragen unterstützen.
- Auf der rechten Seite des Diagramms handelt es sich um Komponenten, die Daten für das Debuggerdatenmodell bereitstellen. Dazu gehören benutzerdefinierte NatVis-, JavaScript- und C++-Debuggerdatenmodellerweiterungen.
Objektmodell
In der Mitte des Debugger-Datenmodells handelt es sich um eine einheitliche Objektdarstellung, in der alles eine Instanz der IModelObject-Schnittstelle ist. Ein solches Objekt kann zwar ein systeminternes (z. B. ein ganzzahliger Wert) oder eine andere Datenmodellschnittstelle darstellen, stellt es jedoch häufig ein dynamisches Objekt dar – ein Wörterbuch mit Schlüssel-Wert-/Metadaten-Tupeln 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 zeigt einen Anbieter, der Informationen für das Objektmodell bereitstellt.
- Auf der linken Seite wird das IModelObject angezeigt, d. h. das allgemeine Objektmodell, das zum Bearbeiten von Objekten verwendet wird.
- Im Zentrum befindet sich der Schlüsselspeicher , der zum Speichern und Zugreifen auf Werte verwendet wird.
- Unten sehen Sie Konzepte , die Objekte mit Funktionen unterstützen, z. B. die Möglichkeit, in eine anzeigefähige Zeichenfolge zu konvertieren oder indiziert zu werden.
Das Datenmodell: Eine Verbrauchersicht
Das nächste Diagramm zeigt eine Consumeransicht des Datenmodells. Im Beispiel wird der Befehl dx (Display Debugger Object Model Expression) verwendet, um Informationen abzufragen.
- Der Befehl Dx kommuniziert über einen Serialisierer an die Objektenumerationsschnittstelle.
- IDebugHost*-Objekte werden verwendet, um Informationen aus dem Debuggermodul zu sammeln.
- Ausdrucks- und semantische Auswertungen werden verwendet, um die Anforderung an das Debuggermodul zu senden.
Das Datenmodell: Eine Produzentenansicht
Dieses Diagramm zeigt eine Produzentenansicht des Datenmodells.
- Auf der linken Seite wird ein NatVis-Anbieter angezeigt, der XML verwendet, der zusätzliche Funktionen definiert.
- Ein JavaScript-Anbieter kann die Vorteile dynamischer Anbieterkonzepte nutzen, um Informationen in Echtzeit zu bearbeiten.
- Unten sehen Sie einen systemeigenen Codeanbieter, 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, eine 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 auf einheitliche und einfache Weise anzugehen, werden sie nach allgemeiner Kategorie aufgeschlüsselt. Die wichtigsten Bereiche hier:
Das allgemeine Objektmodell
Die erste und wichtigste Gruppe von Schnittstellen definieren, wie Sie Zugriff auf das Kerndatenmodell erhalten und wie Sie auf Objekte zugreifen und diese bearbeiten können. IModelObject ist die Schnittstelle, die jedes Objekt im Datenmodell darstellt (ähnlich wie das C#-Objekt). Dies ist die Hauptschnittstelle von Interesse sowohl für Verbraucher als auch für Produzenten bezüglich des Datenmodells. Die anderen Schnittstellen sind Mechanismen für den Zugriff auf verschiedene Aspekte von Objekten. Die folgenden Schnittstellen sind für diese Kategorie definiert:
Brücken zwischen DbgEng und dem Datenmodell
Hauptschnittstellen
IModelKeyReference / IModelKeyReference2
Konzeptschnittstellen
IDynamicConceptProviderConceptProviderConcept
Verwaltung von Datenmodellen und Erweiterbarkeit
Der Datenmodell-Manager ist die Kernkomponente, die verwaltet, wie alle Erweiterbarkeitsfunktionen auftreten. Es ist das zentrale Repository einer Gruppe von Tabellen, die sowohl systemeigene Typen als auch synthetische Konstrukte zu Erweiterungspunkten zuordnen. Darüber hinaus ist es die Entität, die für das Boxen von Objekten (Konvertierung von Ordinalwerten oder Zeichenfolgen in IModelObjects) verantwortlich ist.
Die folgenden Schnittstellen sind für diese Kategorie definiert:
Allgemeiner Datenmodell-Manager-Zugriff
IDataModelManager / IDataModelManager2
Skriptverwaltung
IDataModelScriptProviderEnumerator-
Zugriff auf das Typsystem des Debuggers und Speicherplätze
Das zugrunde liegende Typsystem und Speicherplätze des Debuggers werden für Erweiterungen, die verwendet werden sollen, detailliert verfügbar gemacht. Die folgenden Schnittstellen sind für diese Kategorie definiert:
Allgemeine Hostschnittstellen (Debugger)
IDebugHostMemory / IDebugHostMemory2
IDebugHostEvaluator / IDebugHostEvaluator2
Systemschnittstellen vom Hosttyp (Debugger)
IDebugHostSymbol / IDebugHostSymbol2
IDebugHostType / IDebugHostType2
IDebugHostBaseClassIDebugHostPublic
Hostunterstützung (Debugger) für Skripting
Erstellen und Verwenden von Skripts
Das Datenmodell hat auch eine allgemeine Vorstellung davon, was ein Skript ist und wie ein Skript gedebuggt wird. Es ist völlig möglich, dass eine Debuggererweiterung zusammenkommt und eine allgemeine Brücke zwischen dem Datenmodell und einer anderen dynamischen Sprache (in der Regel eine Skriptumgebung) definiert. Dieser Satz von Schnittstellen ist, wie dies erreicht wird und wie eine Debugger-Benutzeroberfläche solche Skripts verwenden kann.
Die folgenden Schnittstellen sind für diese Kategorie definiert:
Allgemeine Skriptschnittstellen
IDataModelScriptTemplateEnumerator
Skriptdebuggerschnittstellen
IDataModelScriptDebugStackFrame-
IDataModelScriptDebugVariableSetEnumerator
IDataModelScriptDebugBreakpoint-
IDataModelScriptDebugBreakpointEnumerator
Verwenden der DbgModelClientEx-Bibliothek
Übersicht
Die C++-Objektschnittstellen des Datenmodells können sehr aufwendig umgesetzt werden. Sie ermöglichen zwar die vollständige Manipulation des Datenmodells, erfordern jedoch die Implementierung einer Reihe kleiner Schnittstellen, um das Datenmodell zu erweitern (z. B. eine IModelPropertyAccessor-Implementierung für jede dynamische abrufbare Eigenschaft, die hinzugefügt wird). Darüber hinaus fügt das HRESULT-basierte Programmiermodell eine erhebliche Menge von Code für die Kesselplatte hinzu, die 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, das 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::DataModel::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
Wenn Sie sehen möchten, wie die DbgModelClientEx-Bibliothek verwendet werden kann, lesen Sie hier das Data Model HelloWorld C++-Beispiel.
https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld
Das Beispiel umfasst:
HelloProvider.cpp – Dies ist eine Implementierung einer Provider-Klasse, die dem Konzept eines Prozesses im Debugger eine neue Beispieleigenschaft "Hello" hinzufügt.
SimpleIntroExtension.cpp – Dies ist eine einfache Debuggererweiterung, die der Vorstellung eines Prozesses eine neue Beispieleigenschaft "Hello" hinzufügt. Diese Erweiterung wird für die Datenmodell-C++17-Hilfsbibliothek geschrieben. Es ist vorzuziehen, Erweiterungen für diese Bibliothek zu schreiben, anstatt dem rohen COM-ABI, wegen des Umfangs und der Komplexität des notwendigen Klebecodes.
JavaScript- und COM-Beispiele
Um die unterschiedlichen 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 mit dem Datenmodell C++17-Clientbibliothek geschrieben wurde
COM – Eine Version, die mit dem unformatierten COM ABI geschrieben wurde (nur mit WRL für COM-Hilfsprogramme)
Siehe auch
Debuggerdatenmodell-C++-Schnittstellen
Debugger-Datenmodell-C++-Objekte
Zusätzliche Schnittstellen für das Debuggerdatenmodell C++