Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In questo argomento viene fornita una panoramica dell'uso delle interfacce C++ del modello di dati del 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 compilare 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++.
Interfacce C++ del Modello Dati del Debugger
Oggetti C++ del modello di dati del debugger
Interfacce aggiuntive del modello di dati del debugger C++
Concetti relativi al modello di dati del debugger C++
Scripting C++ del modello di dati del debugger
Panoramica dell'interfaccia C++ del modello di dati del debugger
Il modello di 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++) utilizzano informazioni dal debugger e producono informazioni accessibili dal debugger e altre estensioni. I costrutti scritti nelle API del modello di dati sono disponibili nell'analizzatore di espressioni più recente (dx) del debugger, nonché nelle estensioni JavaScript o nelle estensioni C++.
Per illustrare gli obiettivi del modello di dati del debugger, prendere in considerazione 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 debugger usa una maschera binaria e fornisce solo output di testo in modi non standard. L'output di testo è difficile da utilizzare, formattare o estendere e il layout è specifico per questo comando.
Confronta questo con il comando dx (Display Debugger Object Model Expression) del modello di dati del debugger.
dx @$cursession.Processes.Where(p => p.Threads.Count() > 5)
Questo comando usa un modello di dati standard che è individuabile, estendibile e componibile in modo uniforme.
Assegnare un nome logico alla spaziatura e all'estensione su oggetti specifici consente l'individuazione delle funzionalità di estensione del debugger.
Suggerimento
Poiché le interfacce oggetto C++ del modello di dati possono risultare prolisse, è consigliato implementare una libreria helper C++ completa per il modello di dati che utilizza completamente le eccezioni C++ e un paradigma di programmazione a template. 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 sottoposte a script, perché sono basate sul modello di dati. Per altre informazioni, vedere WinDbg - Data Model.
Vista architetturale del modello di dati
Il diagramma seguente riepiloga gli elementi principali dell'architettura del modello di dati del debugger.
- Sul lato sinistro vengono visualizzati gli elementi dell'interfaccia utente che forniscono l'accesso agli oggetti e supportano funzionalità come le query LINQ.
- Sul lato destro del diagramma sono componenti che forniscono dati al modello di dati del debugger. Sono incluse estensioni personalizzate del modello di dati del debugger NatVis, JavaScript e C++.
Modello a oggetti
Al centro del modello di dati del debugger è una rappresentazione uniforme dell'oggetto in cui tutto è un'istanza dell'interfaccia IModelObject. Anche se tale oggetto può rappresentare un valore intrinseco (ad esempio, un valore intero) o un'altra interfaccia del modello di dati, spesso rappresenta un oggetto dinamico, ovvero un dizionario di tuple chiave/valore/metadati e un set di concetti che descrivono comportamenti astratti.
Questo diagramma mostra come IModelObject usa gli archivi chiavi per contenere valori che un provider può creare, registrare e modificare.
- Mostra un provider che fornisce informazioni al modello di oggetti
- A sinistra viene visualizzato l'oggetto 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 oggetti con funzionalità come la possibilità di convertire in una stringa visualizzabile o di essere indicizzati.
Modello dei dati: una vista del consumatore
Il diagramma seguente 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 semantici vengono usati per inviare la richiesta al motore del debugger.
Modello di Dati: Vista del Produttore
Questo diagramma mostra una vista del produttore del modello di dati.
- A sinistra viene visualizzato un provider NatVis che utilizza XML che definisce funzionalità aggiuntive.
- Un provider JavaScript può sfruttare i vantaggi dei concetti del provider dinamico per modificare le informazioni in tempo reale.
- La parte inferiore mostra un provider di codice nativo che può anche definire funzionalità aggiuntive.
Responsabile del Modello Dati
Questo diagramma mostra il ruolo centrale svolto dal gestore di modelli di dati nella gestione degli oggetti.
- Data Model Manager funge da registrar centrale per tutti gli oggetti.
- A sinistra viene illustrato come vengono registrati elementi del debugger standard, ad esempio sessioni e processi.
- Il blocco dello spazio dei nomi mostra l'elenco centrale delle registrazioni.
- 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
Sono disponibili numerose interfacce C++ che comprendono parti diverse del modello di dati. Per affrontare queste interfacce in modo coerente e semplice, vengono suddivise per categoria generale. Le aree principali qui:
Modello a oggetti generale
Il primo e il set più importante di interfacce definiscono 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 di C#). Questa è l'interfaccia principale di interesse sia per gli utenti che per i produttori del modello di dati. Le altre interfacce sono meccanismi per l'accesso a diversi aspetti degli oggetti. Per questa categoria sono definite le interfacce seguenti:
Ponti tra DbgEng e il modello di dati
Interfacce principali
IModelKeyReference / IModelKeyReference2
Interfacce di concetto
IDynamicConceptProviderConcept
Gestione di modelli di dati ed 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 mappano sia i tipi nativi ai punti di estensione sia i costrutti sintetici. Inoltre, è l'entità responsabile dell'incapsulamento (boxing) degli oggetti, ovvero la conversione di valori ordinali o stringhe in IModelObject.
Per questa categoria sono definite le interfacce seguenti:
Accesso generale a Data Model Manager
IDataModelManager / IDataModelManager2
Gestione script
IDataModelScriptProviderEnumerator
Accesso agli spazi di memoria e del sistema dei tipi del debugger
Il sistema dei tipi sottostante e gli spazi di memoria del debugger sono dettagliatamente esposti per permettere l'uso da parte delle estensioni. Per questa categoria sono definite le interfacce seguenti:
Le interfacce host generali del debugger
IDebugHostMemory / IDebugHostMemory2
IDebugHostEvaluator / IDebugHostEvaluator2
Interfacce di sistema del tipo host (debugger)
IDebugHostSymbol / IDebugHostSymbol2
IDebugHostType / IDebugHostType2
IDebugHostBaseClassIDebugHostPublic
Supporto per lo scripting dell'host (debugger)
Creazione e utilizzo di script
Il modello di dati ha anche una nozione generale di cos'è uno script e come eseguirne il debug. È completamente possibile che un'estensione del debugger venga stabilita e definisci un bridge generale tra il modello di dati e un altro linguaggio dinamico (in genere un ambiente di scripting). Questo set di interfacce serve per realizzare questo scopo e anche per consentire a un'interfaccia utente del debugger di utilizzare questi script.
Per questa categoria sono definite le interfacce seguenti:
Interfacce generali degli script
IDataModelScriptTemplateEnumerator
Interfacce del debugger di script
IDataModelScriptDebugStackFrame
IDataModelScriptDebugVariableSetEnumerator
IDataModelScriptDebugBreakpoint
IDataModelScriptDebugBreakpointEnumerator
Uso della libreria DbgModelClientEx
Panoramica
Le interfacce a oggetti 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'eccezione C++ completa e un paradigma di programmazione dei modelli. L'uso di questa libreria consente un codice più conciso quando si utilizza o si estende il modello di dati ed è consigliabile.
Nella libreria di supporto ci sono due namespace importanti:
Debugger::DataModel::ClientEx - Helper per l'utilizzo del modello di dati
Debugger::DataModel::ProviderEx - Helper per l'estensione del modello di dati
Per altre informazioni sull'uso della libreria DbgModelClientEx, vedere il file leggimi in questo sito di 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 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 - Una versione sviluppata per la libreria client del modello di dati C++17
COM - versione scritta contro il COM ABI grezzo (solo con WRL per gli helper COM)
Vedere anche
Interfacce C++ del Modello Dati del Debugger
Oggetti C++ del modello di dati del debugger
Interfacce aggiuntive del modello di dati del debugger C++