Debugger Data Model C++ の概要

このトピックでは、Debugger Data Model C++ のインターフェイスを使用してデバッガーの機能を拡張およびカスタマイズする方法の概要を説明します。

このトピックは、C++ からアクセスできるインターフェイス、それらを使用して C++ ベースのデバッガー拡張機能を構築する方法、および C++ データ モデル拡張機能から他のデータ モデル構造 (JavaScript や NatVis など) を利用する方法を説明するシリーズの一部です。

Debugger Data Model C++ の概要

Debugger Data Model C++ のインターフェイス

Debugger Data Model C++ のオブジェクト

Debugger Data Model C++ のその他のインターフェイス

Debugger Data Model C++ のコンセプト

Debugger Data Model C++ のスクリプト


Debugger Data Model C++ のインターフェイスの概要

このデバッガー データ モデルは、新しいデバッガー拡張機能 (JavaScript、NatVis、C++ で記述されたものを含む) でデバッガーからの情報を利用したり、デバッガーや他の拡張機能からアクセスできる情報を生成したりするしくみの中心となる、拡張可能なオブジェクト モデルです。 データ モデル API に書き込まれるコンストラクトは、デバッガーの新しい (dx) 式エバリュエーターに加え、JavaScript や C++ の拡張機能から使用できます。

デバッガー データ モデルの目標を理解するために、この従来のデバッガー コマンドを検討してみましょう。

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

デバッガー コマンドはバイナリ マスクを使用し、標準以外の方法でテキストのみを出力します。 テキスト出力は使用、書式設定、または拡張が困難であり、レイアウトはこのコマンドに固有です。

これをデバッガー データ モデルの dx (デバッガー オブジェクト モデル式の表示) コマンドと比較してみましょう。

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

このコマンドでは、検出可能で拡張可能、かつ一貫した方法で構成できる標準データ モデルが使用されています。

論理的にスペースに名前を付け、特定のオブジェクトに拡張すると、デバッガー拡張機能の機能を検出できます。

ヒント

Data Model C++ Object のインターフェイスの実装は、場合によっては非常に冗長になるため、完全な C++ 例外とテンプレート プログラミング パラダイムを使用した、データ モデル用の完全な C++ヘルパー ライブラリの実装をお勧めします。 詳細については、このトピックで後述する「DbgModelClientEx ライブラリの使用」を参照してください。

WinDbg ではデータ モデルを使用してほとんどのことが示されます。 新しい UI の多くの要素はデータ モデルが利用されているため、照会、拡張、スクリプト化できます。 詳細については、「WinDbg - データ モデル」を参照してください。

Screenshot of data model explore window displaying process and threads.

データ モデルのアーキテクチャ ビュー

次の図は、デバッガー データ モデル アーキテクチャの主要な要素をまとめたものです。

  • 左側には、オブジェクトへのアクセスを提供し、LINQ クエリなどの機能をサポートする UI 要素が表示されています。
  • 図の右側には、デバッガー データ モデルにデータを提供するコンポーネントがあります。 これには、カスタム NatVis、JavaScript、C++ デバッガー のデータ モデル拡張機能が含まれます。

Diagram that shows data model architecture with common object model in the center and providers on the right.

オブジェクト モデル

Debugger Data Model の中心には統一されたオブジェクト表現があり、これらはすべて IModelObject インターフェイスのインスタンスです。 このようなオブジェクトは、組み込み (整数値など) の場合もあれば、他のデータ モデル インターフェイスを表す場合もありますが、多くの場合、動的オブジェクト (キー/値/メタデータ タプルのディクショナリと、抽象動作を記述するコンセプトのセット) を表します。

以下の図は、IModelObject がキー ストアを使用して、プロバイダーが作成、登録、操作できる値を格納する方法を示しています。

  • この図では、プロバイダーが、オブジェクト モデルに情報を提供しています。
  • 左側には、オブジェクトの操作に使用される一般的なオブジェクト モデルである IModelObject が表示されています。
  • 中央には、値の格納とアクセスに使用されるキー ストアがあります。
  • 下部には、表示可能な文字列に変換する機能やインデックスを作成する機能などの機能によってオブジェクトをサポートするコンセプトが表示されています。

Diagram that shows data model architecture with IModelObject as input and a tuples key store.

データ モデル: コンシューマー ビュー

次の図は、データ モデルのコンシューマー ビューを示しています。 この例では、dx (デバッガー オブジェクト モデル式の表示) コマンドを使用して情報を照会しています。

  • Dx コマンドは、シリアライザーを介してオブジェクト列挙インターフェイスと通信します。
  • IDebugHost* オブジェクトは、デバッガー エンジンから情報を収集するために使用されます。
  • 式エバリュエーターとセマンティック エバリュエーターは、デバッガー エンジンに要求を送信するために使用されます。

Diagram that shows data model architecture with UI feeding into evaluators that connect to IDebugHost.

データ モデル: プロデューサー ビュー

以下の図は、データ モデルのプロデューサー ビューを示しています。

  • 左側に表示されている NatVis プロバイダーは、XML を使用して追加機能を定義します。
  • JavaScript プロバイダーは、動的プロバイダー コンセプトを利用して、リアルタイムで情報を操作できます。
  • 下部には、追加の機能を定義できるネイティブ コード プロバイダーが示されています。

Diagram that shows data model architecture with IModelObject connected to NatVis, JavaScript, and Native code consumers.

データ モデル マネージャー

以下の図は、オブジェクトの管理においてデータ モデル マネージャーが果たす中心的な役割を示しています。

  • データ モデル マネージャーは、すべてのオブジェクトの中央レジストラーとして機能します。
  • 左側には、セッションやプロセスなどの標準デバッガー要素の登録方法が示されています。
  • 名前空間ブロックには、中央登録リストが表示されます。
  • 図の右側には、上部に NatVis 用、下部に C/C++ 拡張機能用の 2 つのプロバイダーが示されています。

Diagram that shows data model architecture with registered names being accessed by the data model manager.

Debugger Data Model のインターフェイスの概略

データ モデルのさまざまな部分を構成する多数の C++ インターフェイスがあります。 これらのインターフェイスに一貫性のある簡単な方法でアプローチするには、一般的なカテゴリ別に分類されます。 メインの領域は次のとおりです。

一般的なオブジェクト モデル

インターフェイスの最初の最も重要なセットは、コア データ モデルにアクセスする方法と、オブジェクトにアクセスして操作する方法を定義します。 IModelObject は、データ モデル内のすべてのオブジェクト (C# のオブジェクトとよく似ています) を表すインターフェイスです。 これは、データ モデルに対するコンシューマーとプロデューサーの両方にとって関心のあるメイン インターフェイスです。 他のインターフェイスは、オブジェクトのさまざまな側面にアクセスするためのメカニズムです。 このカテゴリには、次のインターフェイスが定義されています。

DbgEng とデータ モデル間のブリッジ

IHostDataModelAccess

メイン インターフェイス

IModelObject

IKeyStore

IModelIterator

IModelPropertyAccessor

IModelMethod

IKeyEnumerator

IRawEnumerator

IModelKeyReference / IModelKeyReference2

コンセプト インターフェイス

IStringDisplayableConcept

IIterableConcept

IIndexableConcept

IPreferredRuntimeTypeConcept

IDataModelConcept

IDynamicKeyProviderConcept

IDynamicConceptProviderConcept

データ モデルと拡張性の管理

データ モデル マネージャーは、すべての拡張性の発生方法を管理するコア コンポーネントです。 これは、ネイティブ型を拡張ポイントにマップし、合成コンストラクトを拡張ポイントにマップする一連のテーブルの中央リポジトリです。 さらに、オブジェクトのボックス化 (序数値または文字列の IModelObject への変換) を担当するエンティティです。

このカテゴリには、次のインターフェイスが定義されています。

一般的なデータ モデル マネージャー のアクセス

IDataModelManager / IDataModelManager2

スクリプト管理

IDataModelScriptManager

IDataModelScriptProviderEnumerator

デバッガーの型システムとメモリスペースへのアクセス

デバッガーの基になる型システムとメモリ空間は、拡張機能を利用するために詳細に公開されます。 このカテゴリには、次のインターフェイスが定義されています。

一般的なホスト (デバッガー) インターフェイス

IDebugHost

IDebugHostStatus

IDebugHostContext

IDebugHostMemory / IDebugHostMemory2

IDebugHostErrorSink

IDebugHostEvaluator / IDebugHostEvaluator2

IDebugHostExtensibility

ホスト (デバッガー) 型のシステム インターフェイス

IDebugHostSymbols

IDebugHostSymbol / IDebugHostSymbol2

IDebugHostModule

IDebugHostType / IDebugHostType2

IDebugHostConstant

IDebugHostField

IDebugHostData

IDebugHostBaseClassIDebugHostPublic

IDebugHostModuleSignature

IDebugHostTypeSignature

スクリプトのホスト (デバッガー) のサポート

IDebugHostScriptHost

スクリプトの作成と使用

データ モデルには、スクリプトとは何か、およびスクリプトをデバッグする方法についての一般的な概念もあります。 デバッガー拡張機能が連携して、データ モデルと別の動的言語 (通常はスクリプト環境) の間の一般的なブリッジを定義することは完全に可能です。 このインターフェイスのセットは、これを実現する手段であると同時に、デバッガー UI でこのようなスクリプトを使用する手段です。

このカテゴリには、次のインターフェイスが定義されています。

一般的なスクリプト インターフェイス

IDataModelScriptProvider

IDataModelScript

IDataModelScriptClient

IDataModelScriptHostContext

IDataModelScriptTemplate

IDataModelScriptTemplateEnumerator

IDataModelNameBinder

スクリプト デバッガー インターフェイス

IDataModelScriptDebug

IDataModelScriptDebugClient

IDataModelScriptDebugStack

IDataModelScriptDebugStackFrame

IDataModelScriptDebugVariableSetEnumerator

IDataModelScriptDebugBreakpoint

IDataModelScriptDebugBreakpointEnumerator

DbgModelClientEx ライブラリの使用

概要

データ モデルへの Data Model C++ Object インターフェイスは、実装が非常に煩雑な場合があります。 データ モデルを完全に操作できますが、データ モデルを拡張するには多数の小さなインターフェイスを実装する必要があります (たとえば、追加される動的フェッチ可能なプロパティごとに IModelPropertyAccessor を実装する必要があるなど)。 また、HRESULT ベースのプログラミング モデルでは、エラーのチェックに使用するための追加のボイラー プレート コードが大量に必要です。

この作業の一部を最小限に抑えるために、完全な C++ 例外とテンプレート プログラミング パラダイムを使用するデータ モデル用の完全な C++ ヘルパー ライブラリが用意されています。 このライブラリを使うことで、データモデルの利用や拡張の際に、より簡潔なコードを書くことができます。

ヘルパー ライブラリには、次の 2 つの重要な名前空間があります。

Debugger::D ataModel::ClientEx - データ モデルを使用するためのヘルパー

Debugger::D ataModel::P roviderEx - データ モデルを拡張のするめのヘルパー

DbgModelClientEx ライブラリの使用方法の詳細については、この github サイトの readme ファイルを参照してください。

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

HelloWorld C++ サンプル

DbgModelClientEx ライブラリを使用する方法については、以下の Data Model HelloWorld C++サンプルを確認してください。

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

サンプルには以下のものが含まれています。

  • HelloProvider.cpp - プロセスのデバッガーの概念に新しいサンプル プロパティ "Hello" を追加するプロバイダー クラスの実装です。

  • SimpleIntroExtension.cpp - 新しいサンプル プロパティ "Hello" をデバッガーのプロセスの概念に追加する単純なデバッガー拡張機能です。 この拡張機能は、データ モデル C++17 ヘルパー ライブラリ向けに記述されています。 生の COM ABI では大量の (かつ複雑な) グルー コードが必要になるため、このライブラリに対して拡張機能を記述することを強くお勧めします。

JavaScript と COM のサンプル

データ モデルを使用してデバッガー拡張機能を記述するさまざまな方法をよりよく理解するために、ここでは 3 つのバージョンのデータ モデル HelloWorld 拡張機能が用意されています。

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

  • JavaScript - JavaScript で記述されたバージョン

  • C++17 - データ モデル C++17 クライアント ライブラリに対して記述されたバージョン

  • COM - 生の COM ABI に対して記述されたバージョン (COM ヘルパーに WRL のみを使用)


関連項目

Debugger Data Model C++ のインターフェイス

Debugger Data Model C++ のオブジェクト

Debugger Data Model C++ のその他のインターフェイス

Debugger Data Model C++ のコンセプト

Debugger Data Model C++ のスクリプト