Panoramica del modello di dati del debugger C++
Questo argomento offre una panoramica di come usare interfacce C++ del modello di dati debugger per estendere e personalizzare le funzionalità del debugger.
Questo argomento fa parte di una serie che descrive le interfacce accessibili da C++, come usarle per creare un'estensione del debugger basata su C++ e come usare altri costrutti di modelli di dati (ad esempio JavaScript o NatVis) da un'estensione del modello di dati C++.
Panoramica del modello di dati del debugger C++
Interfacce C++ del modello di dati del debugger
Oggetti C++ del modello di dati debugger
Interfacce aggiuntive del modello di dati del debugger C++
Concetti relativi al modello di dati del debugger C++
Script C++ del modello di dati del debugger
Panoramica dell'interfaccia C++ del modello di dati debugger
Il modello dati del debugger è un modello a oggetti estendibile che è fondamentale per il modo in cui le nuove estensioni del debugger (incluse quelle in JavaScript, NatVis e C++) usano le informazioni del debugger e producono informazioni a cui è possibile accedere dal debugger e altre estensioni. I costrutti scritti nelle API del modello di dati sono disponibili nell'analizzatore di espressioni (dx) più recente del debugger, nonché da estensioni JavaScript o estensioni C++.
Per illustrare gli obiettivi del modello di dati del debugger, considerare questo comando del debugger tradizionale.
0: kd> !process 0 0
PROCESS ffffe0007e6a7780
SessionId: 1 Cid: 0f68 Peb: 7ff7cfe7a000 ParentCid: 0f34
DirBase: 1f7fb9000 ObjectTable: ffffc001cec82780 HandleCount: 34.
Image: echoapp.exe
...
Il comando del debugger usa una maschera binaria e fornisce solo l'output di testo in modi non standard. L'output del testo è difficile da utilizzare, formattare o estendere e il layout è specifico per questo comando.
Contrasto con il comando dx del modello di dati del debugger (Display Debugger Object Model Expression).
dx @$cursession.Processes.Where(p => p.Threads.Count() > 5)
Questo comando usa un modello di dati standard individuabile, estendibile e componibile in modi uniformi.
La spaziatura logica delle cose e l'estensione su oggetti specifici consente l'individuazione delle funzionalità di estensione del debugger.
Suggerimento
Poiché le interfacce oggetto C++ del modello di dati possono essere molto dettagliate per implementare una libreria helper C++ completa per il modello di dati che usa un'eccezione C++ completa e un paradigma di programmazione modello è consigliabile. Per altre informazioni, vedere Uso della libreria DbgModelClientEx più avanti in questo argomento.
Il modello di dati è il modo in cui WinDbg mostra la maggior parte delle cose. Molti elementi nella nuova interfaccia utente possono essere sottoposti a query, estese o script, perché sono basate sul modello di dati. Per altre informazioni, vedere WinDbg - Data Model.
Visualizzazione architettura del modello di dati
Il diagramma seguente riepiloga gli elementi principali dell'architettura del modello di dati del debugger.
- Sul lato sinistro, gli elementi dell'interfaccia utente vengono visualizzati che forniscono l'accesso agli oggetti e supportano tali funzionalità come query LINQ.
- Sul lato destro del diagramma sono componenti che forniscono dati al modello di dati del debugger. Ciò include estensioni del modello di dati del debugger NatVis, JavaScript e C++ personalizzate.
Modello a oggetti
Al centro del Debugger Data Model è una rappresentazione uniforme dell'oggetto in cui tutto è un'istanza dell'interfaccia IModelObject. Sebbene tale oggetto possa rappresentare un oggetto intrinseco (ad esempio, un valore intero) o un'altra interfaccia del modello di dati, spesso rappresenta un oggetto dinamico, un dizionario di tupla chiave/valore/metadati e un set di concetti che descrivono comportamenti astratti.
Questo diagramma illustra come IModelObject usa archivi chiavi per contenere valori che un provider può creare, registrare e modificare.
- Mostra un provider, che fornisce informazioni al modello a oggetti
- A sinistra mostra IModelObject, ovvero il modello a oggetti comune usato per modificare gli oggetti.
- Nel centro è l'archivio chiavi usato per archiviare e accedere ai valori.
- Nella parte inferiore mostra Concetti che supportano gli oggetti con funzionalità, ad esempio la possibilità di convertire in una stringa visualizzabile o di essere indicizzata.
Modello di dati: visualizzazione consumer
Il diagramma successivo mostra una visualizzazione consumer del modello di dati. Nell'esempio viene usato il comando dx (Display Debugger Object Model Expression) per eseguire query sulle informazioni.
- Il comando Dx comunica tramite un serializzatore all'interfaccia di enumerazione dell'oggetto.
- Gli oggetti IDebugHost* vengono usati per raccogliere informazioni dal motore del debugger.
- Gli analizzatori di espressioni e semantiche vengono usati per inviare la richiesta al motore del debugger.
Modello di dati: visualizzazione producer
Questo diagramma mostra una visualizzazione producer del modello di dati.
- Un provider NatVis viene visualizzato a sinistra che usa XML che definisce funzionalità aggiuntive.
- Un provider JavaScript può sfruttare i vantaggi dei concetti del provider dinamico per modificare le informazioni in tempo reale.
- Nella parte inferiore viene visualizzato un provider di codice nativo che può anche definire funzionalità aggiuntive.
Data Model Manager
Questo diagramma mostra il ruolo centrale che il gestore modelli di dati svolge nella gestione degli oggetti.
- Data Model Manager funge da registrar centrale per tutti gli oggetti.
- A sinistra viene illustrato come vengono registrati gli elementi del debugger standard, ad esempio sessioni e processi.
- Il blocco dello spazio dei nomi mostra l'elenco di registrazione centrale.
- Il lato destro del diagramma mostra due provider, uno per NatVis nella parte superiore e un'estensione C/C++ nella parte inferiore.
Riepilogo delle interfacce del modello di dati del debugger
Esistono numerose interfacce C++ che comprendono parti diverse del modello di dati. Per approcciare queste interfacce in modo coerente e semplice, vengono suddivise in base alla categoria generale. Le principali aree qui:
Modello a oggetti generale
Il primo e più importante set di interfacce definisce come ottenere l'accesso al modello di dati principale e come accedere e modificare gli oggetti. IModelObject è l'interfaccia che rappresenta ogni oggetto nel modello di dati (molto simile all'oggetto C#). Si tratta dell'interfaccia principale di interesse sia per i consumatori che per i produttori al modello di dati. Le altre interfacce sono meccanismi per l'accesso a diversi aspetti degli oggetti. Per questa categoria sono definite le interfacce seguenti:
Bridge tra DbgEng e il modello di dati
Interfacce principali
IModelKeyReference / IModelKeyReference2
Interfacce di concetto
IDynamicConceptProviderConcept
Gestione di modelli di dati e estendibilità
Data Model Manager è il componente principale che gestisce il modo in cui si verifica tutta l'estendibilità. È il repository centrale di un set di tabelle che esegue il mapping di entrambi i tipi nativi ai punti di estensione e ai costrutti sintetici ai punti di estensione. Inoltre, è l'entità responsabile del boxing di oggetti (conversione di valori ordinali o stringhe in IModelObject).
Per questa categoria sono definite le interfacce seguenti:
Accesso di General Data Model Manager
IDataModelManager / IDataModelManager2
Gestione script
IDataModelScriptProviderEnumerator
Accesso agli spazi di sistema dei tipi e della memoria del debugger
Gli spazi di memoria e di sistema dei tipi sottostanti del debugger vengono esposti in dettaglio per le estensioni da usare. Per questa categoria sono definite le interfacce seguenti:
Interfacce host generali (debugger)
IDebugHostMemory / IDebugHostMemory2
IDebugHostEvaluator / IDebugHostEvaluator2
Interfacce di sistema del tipo host (debugger)
IDebugHostSymbol / IDebugHostSymbol2
IDebugHostType / IDebugHostType2
IDebugHostBaseClassIDebugHostPublic
Supporto host (debugger) per lo scripting
Creazione e utilizzo di script
Il modello di dati ha anche una nozione generale di che cos'è uno script e come eseguirne il debug. È possibile che un'estensione del debugger venga eseguita e definiscano un ponte generale tra il modello di dati e un altro linguaggio dinamico (in genere un ambiente di scripting). Questo set di interfacce è il modo in cui viene eseguita e come un'interfaccia utente del debugger può usare tali script.
Per questa categoria sono definite le interfacce seguenti:
Interfacce script generali
IDataModelScriptTemplateEnumerator
Interfacce del debugger di script
IDataModelScriptDebugStackFrame
IDataModelScriptDebugVariableSetEnumerator
IDataModelScriptDebugBreakpoint
IDataModelScriptDebugBreakpointEnumerator
Uso della libreria DbgModelClientEx
Panoramica
Le interfacce oggetto C++ del modello di dati per il modello di dati possono essere molto verbose da implementare. Sebbene consentano la manipolazione completa del modello di dati, richiedono l'implementazione di una serie di interfacce di piccole dimensioni per estendere il modello di dati ,ad esempio un'implementazione IModelPropertyAccessor per ogni proprietà recuperabile dinamica aggiunta. Oltre a questo, il modello di programmazione basato su HRESULT aggiunge una quantità significativa di codice della lastra caldaia usato per il controllo degli errori.
Per ridurre al minimo alcune di queste operazioni, è disponibile una libreria helper C++ completa per il modello di dati che usa un paradigma di programmazione di modelli e eccezioni C++ completo. L'uso di questa libreria consente un codice più conciso quando si utilizza o si estende il modello di dati ed è consigliabile.
Nella libreria helper sono presenti due spazi dei nomi importanti:
Debugger::D ataModel::ClientEx - Helper per l'utilizzo del modello di dati
Debugger::D ataModel::P roviderEx - Helper per l'estensione del modello di dati
Per altre informazioni sull'uso della libreria DbgModelClientEx, vedere il file readme in questo sito github:
https://github.com/Microsoft/WinDbg-Libraries/tree/master/DbgModelCppLib
Esempio di C++ HelloWorld
Per informazioni sull'uso della libreria DbgModelClientEx, vedere l'esempio di Data Model HelloWorld C++ qui.
https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld
L'esempio include:
HelloProvider.cpp: si tratta di un'implementazione di una classe provider che aggiunge una nuova proprietà di esempio "Hello" alla nozione del debugger di un processo.
SimpleIntroExtension.cpp: si tratta di una semplice estensione del debugger che aggiunge una nuova proprietà di esempio "Hello" alla nozione del debugger di un processo. Questa estensione viene scritta nella libreria helper C++17 del modello di dati. È preferibile scrivere estensioni in questa libreria anziché nell'ABI COM non elaborato a causa del volume (e della complessità) del codice glue necessario.
Esempi di JavaScript e COM
Per comprendere meglio i diversi modi per scrivere un'estensione del debugger con il modello di dati, sono disponibili tre versioni dell'estensione HelloWorld del modello di dati qui:
https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld
JavaScript - Versione scritta in JavaScript
C++17 - Versione scritta sulla libreria client C++17 del modello di dati
COM: versione scritta nell'interfaccia ABI COM non elaborata (solo con WRL per gli helper COM)
Vedere anche
Interfacce C++ del modello di dati del debugger
Oggetti C++ del modello di dati del debugger
Interfacce aggiuntive del modello di dati del debugger C++