_ATL_DEBUG_INTERFACES
更新 : 2007 年 11 月
ATL ヘッダー ファイルをインクルードする前にこのマクロを定義して、コンポーネントのインターフェイスでの AddRef 呼び出しと Release 呼び出しをすべて出力ウィンドウにトレースします。
#define _ATL_DEBUG_INTERFACES
解説
トレース出力は次のように表示されます。
ATL: QIThunk - 2008 AddRef : Object = 0x00d81ba0 Refcount = 1 CBug - IBug
各トレースの最初の部分は、常に ATL: QIThunk です。次の部分は、使用中の特定のインターフェイス サンクを識別する値です。インターフェイス サンクとは、参照カウントの保持およびここで使用されるトレース機能の提供に使用されるオブジェクトです。新規インターフェイス サンクは、IUnknown インターフェイスの要求を除いて、QueryInterface の呼び出しのたびに作成されます。IUnknown インターフェイスの要求では、COM の ID 規則に準拠するために、常に同じサンクが返されます。
次に、どのメソッドが呼び出されたかを示す AddRef または Release が表示されます。その後には、インターフェイスの参照カウントが変更されたオブジェクトを識別する値が表示されます。トレースされる値は、オブジェクトの this ポインタです。
トレースされる参照カウントは、AddRef または Release が呼び出された後のそのサンクの参照カウントです。この参照カウントは、オブジェクトの参照カウントと一致しないことがあります。各サンクには、COM の参照カウント規則に完全に準拠するために役立つ独自の参照カウントが保持されます。
トレースされる情報の最後の部分は、AddRef または Release の呼び出しによって影響を受けるオブジェクトとインターフェイスの名前です。
サーバーのシャットダウン時および _Module.Term 呼び出し時に検出されるインターフェイス リークは、次のようにログに記録されます。
ATL: QIThunk - 2005 LEAK : Object = 0x00d81ca0 Refcount = 1 MaxRefCount = 1 CBug - IBug
ここで提供される情報は、以前のトレース ステートメントで提供された情報に直接対応するため、インターフェイス サンクの有効期間全体を通じて参照カウントを調べることができます。さらに、そのインターフェイス サンクの最大の参照カウントの表示を取得します。
メモ : |
---|
_ATL_DEBUG_INTERFACES はリテール ビルドで使用できます。 |
ヒント
Refcount が 1 の AddRef 呼び出しを参照すると、どの時点で新しいインターフェイス サンクが作成されたかがわかります。
Refcount が 0 の Release 呼び出しを参照すると、どの時点でインターフェイス サンクが破棄されたかがわかります。
トレース ステートメントの出力はタブ区切り形式なので、データの切り取りやスプレッドシートへの貼り付けが簡単にできます。Microsoft Excel などを利用すると、フィルタ処理、検索、並べ替えなどの高度な処理を行うことができます。
_ATL_DEBUG_INTERFACES の未定義時にはコードが正常に機能するが、定義するとアクセス違反が発生する場合は、クライアント コードに参照カウントの不一致によるバグがあると考えられます。このような例を次に示します。
IBug* pBug = NULL; hr = p->QueryInterface(&pBug); ATLASSERT(SUCCEEDED(hr)); IBug* pBug2 = NULL; hr = p->QueryInterface(&pBug2); ATLASSERT(SUCCEEDED(hr)); pBug->Release(); pBug->Release(); // Mismatched - should be pBug2->Release();
このコードは、一部の状況では正しく機能することもありますが、明らかに問題があります。このコードを完全に正しく機能させるためには、IBug インターフェイスを提供する COM オブジェクトの実装の詳細によって異なります (IBug はティアオフ インターフェイスとして実装できません)。また、場所によっても異なります。クライアントは IBug の実装と同じアパートメントにある必要があります。_ATL_DEBUG_INTERFACES マクロを使用すると、このようなバグを発見できます。