Partilhar via


Visão Geral do Modelo de Dados do Depurador C++

Este tópico fornece uma visão geral de como usar as interfaces C++ do Modelo de Dados do Depurador para estender e personalizar os recursos do depurador.

Este tópico faz parte de uma série que descreve as interfaces acessíveis a partir de C++, como usá-las para criar uma extensão de depurador baseada em C++ e como fazer uso de outras construções de modelo de dados (por exemplo: JavaScript ou NatVis) a partir de uma extensão de modelo de dados C++.

Interfaces do modelo de dados do depurador C++

Objetos C++ do modelo de dados do depurador

Interfaces adicionais do Debugger Data Model C++

Conceitos do Depurador Data Model C++

Script C++ do modelo de dados do depurador


Visão geral da interface C++ do modelo de dados do depurador

O modelo de dados do depurador é um modelo de objeto extensível que é central para a maneira como as novas extensões do depurador (incluindo aquelas em JavaScript, NatVis, e C++) consomem informações do depurador e produzem informações que podem ser acessadas a partir do depurador, bem como outras extensões. As construções que são registadas nas APIs do modelo de dados estão disponíveis no avaliador de expressões mais recente (dx) do depurador, assim como em extensões para JavaScript ou C++.

Para ilustrar os objetivos do modelo de dados do depurador, considere este comando tradicional do depurador.

0: kd> !process 0 0 
PROCESS ffffe0007e6a7780
    SessionId: 1  Cid: 0f68    Peb: 7ff7cfe7a000  ParentCid: 0f34
    DirBase: 1f7fb9000  ObjectTable: ffffc001cec82780  HandleCount:  34.
    Image: echoapp.exe
...

O comando do depurador está usando uma máscara binária e fornece apenas saída de texto de maneiras não padrão. A saída de texto é difícil de consumir, formatar ou estender e o layout é específico para este comando.

Contraste isto com o comando de modelo de dados do debugger dx (Display Debugger Object Model Expression).

dx @$cursession.Processes.Where(p => p.Threads.Count() > 5)

Este comando usa um modelo de dados padrão que é detetável, extensível e compostável de maneiras uniformes.

Logicamente, o espaçamento entre nomes e a extensão em objetos específicos permitem a descoberta da funcionalidade de extensão do depurador.

Sugestão

Como as interfaces de objeto C++ do Modelo de Dados podem ser muito detalhadas, recomenda-se implementar uma biblioteca auxiliar C++ completa para o modelo de dados, que utiliza a totalidade das capacidades de tratamento de exceções C++ e segue o paradigma de programação de templates. Para obter mais informações, consulte Usando a biblioteca DbgModelClientEx mais adiante neste tópico.

O modelo de dados é a forma como o WinDbg mostra a maioria das coisas. Muitos elementos na nova interface de utilizador podem ser consultados, estendidos ou programados, porque são suportados pelo modelo de dados. Para obter mais informações, consulte WinDbg - Modelo de dados.

Captura de tela da janela de exploração do modelo de dados exibindo o processo e os threads.

Visualização arquitetônica do modelo de dados

O diagrama a seguir resume os principais elementos da arquitetura do modelo de dados do depurador.

  • No lado esquerdo, são mostrados elementos da interface do usuário que fornecem acesso aos objetos e suportam funcionalidades como consultas LINQ.
  • No lado direito do diagrama estão componentes que fornecem dados para o modelo de dados do depurador. Isso inclui extensões personalizadas do modelo de dados do depurador NatVis, JavaScript e C++.

Diagrama que mostra a arquitetura do modelo de dados com o modelo de objeto comum no centro e provedores à direita.

Modelo de objeto

No centro do Modelo de Dados do Depurador está uma representação de objeto uniforme na qual tudo é uma instância da interface IModelObject. Embora tal objeto possa representar um intrínseco (por exemplo: um valor inteiro) ou outra interface de modelo de dados, ele geralmente representa um objeto dinâmico – um dicionário de tuplas de chave/valor/metadados e um conjunto de conceitos que descrevem comportamentos abstratos.

Este diagrama mostra como o IModelObject usa Key Stores para conter valores que um provedor pode criar, registrar e manipular.

  • Ele mostra um provedor, que fornece informações para o modelo de objeto
  • À esquerda, ele mostra o IModelObject, que é o modelo de objeto comum que é usado para manipular objetos.
  • No centro está o Key Store que é usado para armazenar e acessar valores.
  • Na parte inferior, ele mostra Conceitos que suportam objetos com funcionalidades, como a capacidade de converter para uma string legível ou serem indexados.

Diagrama que mostra a arquitetura do modelo de dados com IModelObject como entrada e um armazenamento de chaves de tuplas.

O modelo de dados: uma visão do consumidor

O diagrama seguinte mostra uma visão do consumidor do modelo de dados. No exemplo, o comando dx (Display Debugger Object Model Expression) está sendo usado para consultar informações.

  • O comando Dx se comunica por meio de um serializador com a interface de enumeração de objetos.
  • IDebugHost* objetos são usados para coletar informações do mecanismo de depurador.
  • Os avaliadores semânticos e de expressão são usados para enviar a solicitação para o mecanismo do depurador.

Diagrama que mostra a arquitetura do modelo de dados com a interface do usuário alimentando os avaliadores que se conectam ao IDebugHost.

O modelo de dados: uma visão do produtor

Este diagrama mostra uma visão do produtor do modelo de dados.

  • Um provedor NatVis é mostrado à esquerda, consumindo XML que define funcionalidade adicional.
  • Um provedor JavaScript pode tirar proveito dos conceitos de provedor dinâmico para manipular informações em tempo real.
  • A parte inferior mostra um provedor de código nativo que também pode definir funcionalidades adicionais.

Diagrama que mostra a arquitetura do modelo de dados com IModelObject conectado a NatVis, JavaScript e consumidores de código nativo.

Gestor de Modelo de Dados

Este diagrama mostra o papel central que o gerenciador de modelo de dados desempenha no gerenciamento de objetos.

  • O Gerenciador de Modelo de Dados atua como um registrador central para todos os objetos.
  • À esquerda, mostra como os elementos padrão do depurador, como sessões e processos, são registrados.
  • O bloco de namespace mostra a lista de registro central.
  • O lado direito do diagrama mostra dois provedores, um para NatVis na parte superior e uma extensão C/C++ na parte inferior.

Diagrama que mostra a arquitetura do modelo de dados com nomes registrados sendo acessados pelo gerenciador do modelo de dados.

Resumo das interfaces do modelo de dados do depurador

Há uma infinidade de interfaces C++ que compreendem diferentes partes do modelo de dados. A fim de abordar essas interfaces de forma consistente e fácil, elas são divididas por categoria geral. As principais áreas aqui:

O modelo de objeto geral

O primeiro e mais importante conjunto de interfaces define como obter acesso ao modelo de dados principal e como acessar e manipular objetos. IModelObject é a interface que representa todos os objetos no modelo de dados (muito parecido com o objeto do C#). Esta é a principal interface de interesse tanto para os consumidores quanto para os produtores do modelo de dados. As outras interfaces são mecanismos para acessar diferentes aspetos dos objetos. As seguintes interfaces são definidas para esta categoria:

Pontes entre o DbgEng e o modelo de dados

IHostDataModelAccess

Principais Interfaces

IModelObject

IKeyStore

IModelIterator

IModelPropertyAccessor

IModelMethod

IKeyEnumerator

IRawEnumerator

IModelKeyReference / IModelKeyReference2

Interfaces Conceptuais

IStringDisplayableConcept

IIterableConcept

IIndexableConcept

IPreferredRuntimeTypeConcept

IDataModelConcept

IDynamicKeyProviderConcept

IDynamicConceptProviderConcept

Gestão de Modelos de Dados e Extensibilidade

O Data Model Manager é o componente principal que gerencia como toda a extensibilidade ocorre. É o repositório central de um conjunto de tabelas que mapeiam tanto tipos nativos para pontos de extensão como construções sintéticas para pontos de extensão. Além disso, é a entidade responsável pela conversão (ou 'boxing') de objetos, transformando valores ordinais ou strings em IModelObjects.

As seguintes interfaces são definidas para esta categoria:

Acesso ao Gerente Geral de Modelo de Dados

IDataModelManager / IDataModelManager2

Gestão de Scripts

IDataModelScriptManager

IDataModelScriptProviderEnumerator

Acesso ao sistema de tipos e aos espaços de memória do Depurador

O sistema de tipos subjacente e os espaços de memória do depurador são expostos em detalhe para serem utilizadas pelas extensões. As seguintes interfaces são definidas para esta categoria:

Interfaces gerais de host (depurador)

IDebugHost

IDebugHostStatus

IDebugHostContext

IDebugHostMemory / IDebugHostMemory2

IDebugHostErrorSink

IDebugHostEvaluator / IDebugHostEvaluator2

IDebugHostExtensibility

Interfaces de sistema do tipo host (depurador)

IDebugHostSymbols

IDebugHostSymbol / IDebugHostSymbol2

IDebugHostModule

IDebugHostType / IDebugHostType2

IDebugHostConstant

IDebugHostField

IDebugHostData

IDebugHostBaseClassIDebugHostPublic

IDebugHostModuleSignature

IDebugHostTypeSignature

Suporte de host (depurador) para scripts

IDebugHostScriptHost

Criação e consumo de scripts

O Modelo de Dados também tem uma noção geral do que é um script e como depurá-lo. É totalmente possível que uma extensão do depurador apareça e defina uma ponte geral entre o modelo de dados e outra linguagem dinâmica (geralmente um ambiente de script). Esse conjunto de interfaces é como isso é feito, bem como como uma interface do usuário do depurador pode fazer uso desses scripts.

As seguintes interfaces são definidas para esta categoria:

Interfaces de Script Gerais

IDataModelScriptProvider

IDataModelScript

IDataModelScriptClient

IDataModelScriptHostContext

IDataModelScriptTemplate

IDataModelScriptTemplateEnumerator

IDataModelNameBinder

Interfaces do depurador de scripts

IDataModelScriptDebug

IDataModelScriptDebugClient

IDataModelScriptDebugStack

IDataModelScriptDebugStackFrame

IDataModelScriptDebugVariableSetEnumerator

IDataModelScriptDebugBreakpoint

IDataModelScriptDebugBreakpointEnumerator (Enumerador de Pontos de Paragem para Debug de Script do Modelo de Dados)

Usando a biblioteca DbgModelClientEx

Visão geral

As interfaces de objeto C++ do modelo de dados para o modelo de dados podem ser muito detalhadas de implementar. Embora permitam a manipulação completa do modelo de dados, eles exigem a implementação de várias pequenas interfaces para estender o modelo de dados (por exemplo: uma implementação IModelPropertyAccessor para cada propriedade dinâmica fetchable que é adicionada). Além disso, o modelo de programação baseado em HRESULT adiciona uma quantidade significativa de código de placa clichê que é usado para verificação de erros.

Para minimizar parte desse trabalho, há uma biblioteca auxiliar C++ completa para o modelo de dados que usa uma exceção C++ completa e um paradigma de programação de modelo. O uso dessa biblioteca permite um código mais conciso ao consumir ou estender o modelo de dados e é recomendado.

Há dois namespaces importantes na biblioteca auxiliar:

Depurador::DataModel::ClientEx - auxiliares para utilização do modelo de dados

Debugger::DataModel::ProviderEx - auxiliares para extensão do modelo de dados

Para obter informações adicionais sobre como usar a biblioteca DbgModelClientEx, consulte o arquivo readme neste site do github:

https://github.com/Microsoft/WinDbg-Libraries/tree/master/DbgModelCppLib

Exemplo de HelloWorld C++

Para ver como a biblioteca DbgModelClientEx pode ser usada, examine o exemplo de modelo de dados HelloWorld C++ aqui.

https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld

A amostra inclui:

  • HelloProvider.cpp - Esta é uma implementação de uma classe de provedor que adiciona uma nova propriedade de exemplo "Hello" à noção do depurador de um processo.

  • SimpleIntroExtension.cpp - Esta é uma extensão de depurador simples que adiciona uma nova propriedade de exemplo "Hello" à noção de um processo do depurador. Esta extensão é escrita em relação à Biblioteca Auxiliar do Modelo de Dados C++17. É muito preferível escrever extensões nesta biblioteca em vez do ABI COM bruto devido ao volume (e complexidade) do código de cola que é necessário.

Exemplos de JavaScript e COM

Para entender melhor as várias maneiras de escrever uma extensão do depurador com o modelo de dados, há três versões da extensão HelloWorld do modelo de dados disponíveis aqui:

https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld

  • JavaScript - Uma versão escrita em JavaScript

  • C++17 - Uma versão escrita na biblioteca de cliente C++17 do Modelo de Dados

  • COM - Uma versão escrita contra o COM ABI bruto (usando apenas WRL para auxiliares COM)


Ver também

Interfaces do modelo de dados do depurador C++

Objetos C++ do modelo de dados do depurador

Interfaces adicionais do Debugger Data Model C++

Conceitos de Modelo de Dados do Depurador C++

Script de C++ do modelo de dados do depurador