_ATL_DEBUG_INTERFACES
ATL ヘッダー ファイルをインクルードする前にこのマクロを定義して、コンポーネントのインターフェイスでの AddRef 呼び出しと Release 呼び出しをすべて出力ウィンドウにトレースします。
#define _ATL_DEBUG_INTERFACES
解説
トレース出力は、次に示すように表示されます:
ATL: QIThunk - 2008 AddRef : Object = 0x00d81ba0 Refcount = 1 CBug - IBug
各トレースの最初の部分では ATL: QIThunk常にです。使用する特定の インターフェイスのサンクを 識別する値はになります。インターフェイスのサンクは参照カウントを保持し、次に使用されるトレース機能を提供するために使用するオブジェクトです。新しいインターフェイスのサンクは要求を除く IUnknown のインターフェイスの QueryInterface へのすべての呼び出しに作成されます (この場合、同じサンクは COM ID の規則に準拠するたびにが返されます)。
次に AddRef か [リリース] のメソッドが呼び出されたことを示すが表示されます。これに従って、値をインターフェイスの参照カウントが変更されたオブジェクトを識別することを確認します。たどられる値は、オブジェクトの this のポインターです。
たどられる参照カウントが AddRef か [リリース] が呼び出された後、サンクの参照カウントです。この参照カウントがオブジェクトの参照カウントに一致しない場合があることに注意してください。各サンクは、COM 参照カウント規則に準拠のを完全に役立つように、の参照カウントを保持します。
たどられる最終的な情報は AddRef または [リリース] の呼び出しによって影響を受けるオブジェクトとインターフェイスの名前です。
サーバーがシャットダウン記録されます _Module.Term 呼び出され、検出されたときにどのインターフェイスのリークには次のように:
ATL: QIThunk - 2005 LEAK : Object = 0x00d81ca0 Refcount = 1 MaxRefCount = 1 CBug - IBug
ここで指定した情報は、以前のトレース ステートメントで指定された情報に直接割り当てられます。このインターフェイスのサンクのすべての有効期間中の参照カウントを確認できます。さらに、そのインターフェイスのサンクの最大の参照カウントを示す値を取得します。
[!メモ]
_ATL_DEBUG_INTERFACES は、リリース ビルドで使用できます。
ヒント
新しいインターフェイスのサンクが 1.で Refcount の AddRef の呼び出しを検索することにより、作成時に確認できます。
インターフェイスのサンクが 0 かの Refcount の 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 インターフェイス (IBug 実行できないのでティアオフ インターフェイス) を提供する COM オブジェクトの実装の詳細と、位置に依存です (クライアントは IBug の実装と同じアパートメント内にある必要があります)。_ATL_DEBUG_INTERFACES マクロの使用を有効にするには、このようなバグを取り込むことができます。