EEAddIn サンプル : デバッグ用の式エバリュエータ アドイン

更新 : 2007 年 11 月

EEAddin サンプルでは、式エバリュエータ アドイン API を使用してネイティブ デバッガの式エバリュエータを拡張する方法を示します。

8fwk67y3.alert_security(ja-jp,VS.90).gifセキュリティに関するメモ :

このサンプル コードは概念を示す目的で提供されているものです。必ずしも最も安全なコーディング手法に従っているわけではないため、アプリケーションまたは Web サイトでは使用しないでください。Microsoft は、サンプル コードが意図しない目的で使用された場合に、付随的または間接的な損害について責任を負いません。

サンプルとそのインストール手順を取得するには

  • Visual Studio で、[ヘルプ] メニューの [サンプル] をクリックします。

    詳細については、「サンプル ファイルの格納場所」を参照してください。

  • 使用できるサンプルの最新バージョンと完全な一覧については、オンラインの Visual Studio 2008 Samples のページを参照してください。

  • サンプルは、コンピュータのハード ディスク上にもあります。既定では、サンプルおよび Readme ファイルは、\Program Files\Visual Studio 9.0\Samples\ の下のフォルダにコピーされます。Visual Studio Express Edition の場合、すべてのサンプルはオンライン上にあります。

EE アドイン API

式エバリュエータは、式を解釈 (評価) するデバッガ部分です。デバッガ ウィンドウで、式にブレークポイントを設定したり、式を入力したりすると、式エバリュエータが入力を評価します。詳細については、「デバッガ内の式」を参照してください。式エバリュエータ アドイン API を使用すると、式エバリュエータを拡張して新しいデータ型を処理できます。

新しいデータ型を処理できるように式エバリュエータを拡張するには、autoexp.dat と同じディレクトリにある Win32 DLL の一部として関数を作成し、関数名をエクスポートする必要があります。また、autoexp.dat ファイルにも行を追加する必要があります。DLL から複数の関数をエクスポートして、1 つ以上のデータ型に対して式エバリュエータを拡張できます。

サンプルのビルドと実行

このサンプルのビルドと実行に必要な手順は、次の 3 つの部分から成ります。

サンプルをビルドして実行するには

  1. 式エバリュエータ アドイン DLL (eeaddin.dll) をビルドします。

  2. 式エバリュエータ アドイン DLL を使用できるように autoexp.dat を編集します。

  3. autoexp.dat によって評価されるカスタム データ型を使用するプロジェクトを作成して、アドインをテストします。

これらの手順の詳細は、次のとおりです。

式エバリュエータ アドイン DLL をビルドするには

  1. Visual Studio で、eeaddin.sln ソリューション ファイルを開きます。

  2. [ビルド] メニューの [ビルド] をクリックします。

  3. 結果の eeaddin.dll を common7\ide ディレクトリ (devenv.exe が含まれているディレクトリ) にコピーします。

  4. [ファイル] メニューの [ソリューションを閉じる] をクリックします。

autoexp.dat を編集するには

  1. [ファイル] メニューの [開く] をポイントし、[ファイル] をクリックします。

  2. [ファイルを開く] ダイアログ ボックスで、common7\packages\debugger ディレクトリの autoexp.dat ファイルを探し、[開く] をクリックします。

  3. autoexp.dat を編集して、次の行を追加します。

    _SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime@28)
    _FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime@28)
    

    autoexp.dat を保存します。

カスタム データ型を使用するプロジェクトを作成するには

  1. [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。

  2. [新しいプロジェクト] ダイアログ ボックスの [Visual C++ プロジェクト] を強調表示します。次に、[MFC アプリケーション] をクリックし、プロジェクトの名前を入力して [OK] をクリックします。

  3. MFC アプリケーション ウィザードで、[完了] をクリックします。このプロジェクトは、以下の手順で示す MFC 関数を追加するために、MFC アプリケーションとして作成する必要があります。

  4. MFC アプリケーションに、SYSTEMTIME オブジェクトまたは FILETIME オブジェクトを追加します。

    SYSTEMTIME *s = new SYSTEMTIME();
    FILETIME *f = new FILETIME();
    GetSystemTime(s);
    SystemTimeToFileTime(s,f);
    
  5. [ビルド] メニューの [ビルド] をクリックします。

  6. デバッグを開始し、ウォッチ ウィンドウで SYSTEMTIME オブジェクトまたは FILETIME オブジェクトを確認します。

サンプルの動作

カスタム データ型を処理できるように式エバリュエータを拡張するには、式エバリュエータ アドインの DLL にカスタム ビューア関数を作成します。この関数は、拡張する式エバリュエータのメモリ空間ではなく、デバッグされるプログラムのメモリ空間にあるオブジェクトへのポインタを使用します。このポインタでは、通常のキャストは使用できません。コールバック関数を使用して、ポインタおよびポインタが指すデータを読み取る必要があります。DEBUGHELPER* 型のコールバック ポインタは、さまざまなメソッドにおいてオブジェクトを指します。

構文は次のようになります。

HRESULT WINAPI CustomViewer(
   DWORD dwAddress,       // low 32-bits of address
   DEBUGHELPER *pHelper,  // callback pointer to access helper functions
   int nBase,             // decimal or hex
   BOOL bIgnore,          // not used
   char *pResult,         // where the result needs to go
   size_t max,            // how large the above buffer is
   DWORD dwReserved       // always pass zero
)

サンプルには、この種類の関数が 2 つ実装されています。timeaddin.cpp の AddIn_SystemTime と AddIn_FileTime です。custview.h で定義されている DEBUGHELPER 構造体は、拡張を作成するときに役立つ関数ポインタで構成されています。このポインタを CustomViewer 関数に渡して、ヘルパー関数の呼び出しに使用します。

プロセッサの種類は、pHelper->GetProcessorType で取得できます。メモリを読み取るには、pHelper->ReadDebuggeeMemory と pHelper->ReadDebuggeeMemoryEx の 2 つのメソッドがあります。ReadDebuggeeMemoryEx は、64 ビット アドレスを処理し、Visual Studio .NET デバッガによってサポートされています。ReadDebuggeeMemory は、64 ビット アドレスを処理せず、Visual Studio .NET および Visual C++ 6.0 デバッガによってサポートされています。作成するアドインが Visual Studio .NET デバッガ専用の場合は、ReadDebuggeeMemoryEx を使用します。作成するアドインを Visual C++ 6.0 でも使用する場合は、dwVersion フィールドを確認し、Visual C++ 6.0 に対して ReadDebuggeeMemoryEx を呼び出さないようにする必要があります。

次のコードは、両方のデバッガで使用でき、デバッグされるプログラムから MyType 型の localobject の内容を読み取ります。

DWORDLONG qwRealAddress;
DWORD dwGot;
MyType localobject;
if (pHelper->dwVersion<0x20000)
{
   // Visual C++ 6.0 version
   qwRealAddress = dwAddress;
   pHelper->ReadDebuggeeMemory( pHelper, dwAddress, 
      sizeof(localobject), &localobject, &dwGot );
}
else
{
   qwRealAddress = pHelper->GetRealAddress(pHelper);
   pHelper->ReadDebuggeeMemoryEx( pHelper, qwRealAddress, 
      sizeof(localobject), &localobject, &dwGot );
}
// TODO: display localobject here

autoexp.dat の編集

autoexp.dat の [AutoExpand] セクションに追加する行の構文は、次のとおりです。

type=$ADDIN(dllname.dll,exportname)

次に例を示します。

_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime)

または

_FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime)

DLL が devenv.exe と同じディレクトリにないか、または PATH のディレクトリにないときは、DLL の完全パス名を使用する必要があります。引数 exportname では大文字と小文字が区別され、DLL で dumpbin –exports を実行したときに取得されるエクスポート名と正確に一致している必要があります。

新しいアドインを使用してデバッガをテストするには、新しい DLL のインストール時にデバッグしていたプログラムがある場合は、まずそれらのデバッグをすべて中止します。その後、新しいデバッガ セッションを開始します。

メモ   アドインはデバッガ内で動作します。このため、コードがクラッシュすると、IDE がクラッシュします。

参照

その他の技術情報

一般的なサンプル