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

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

セキュリティに関するメモセキュリティに関するメモ

このサンプル コードは概念を示すためのものであり、その概念に関連するコードのみを示しています。 特定の環境について必ずしもセキュリティ要件を満たしていませんので、そのまま使用しないでください。 セキュリティおよびエラー処理コードを追加して、プロジェクトをより安全かつ堅牢にすることをお勧めします。 これらのサンプル コードは、現状有姿のままで提供されるものであり、一切保証されていません。

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

Visual Studio のサンプルにアクセスするには

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

    既定では、これらのサンプルは drive:\Program Files\Microsoft Visual Studio 10.0\Samples\ にインストールされています。

  • このサンプルの最新バージョンと他のサンプルの一覧については、MSDN Web サイトの Visual Studio のサンプルを参照してください。

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 は、Visual Studio .NET デバッガーによってサポートされ、64 ビット アドレスを処理します。 ReadDebuggeeMemory は、Visual Studio .NET と Visual C++ 6.0 の各デバッガーによってサポートされ、64 ビット アドレスは処理しません。 作成するアドインが 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 がクラッシュします。

参照

その他の技術情報

一般的なサンプル