DebugExtensionProvideValue
カスタム疑似レジスタを提供できるように、拡張機能に実装しています。CDB では完全に動作し、WinDbg では最初は正常に動作しますが、デバッグを停止して新しい実行可能ファイルを開くと、何かが発生し、WinDbg は奇妙な使用不能状態になります。
問題が発生すると、WinDbg は次のメッセージをコマンド ウィンドウに出力します。
コールバックを配信できません、3131
これが発生した後、WinDbg はすべての出力をコマンド ウィンドウに 2 回出力するようです!
私の拡張コードは非常に単純です:
EXTERN_C HRESULT CALLBACK DebugExtensionProvideValue(PDEBUG_CLIENT Client, ULONG Flags, IN PCWSTR Name, OUT PULONG64 Value, OUT PULONG64 TypeModBase, OUT PULONG TypeId, OUT PULONG TypeFlags)
{
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
if (!Name || !Value || !TypeFlags)
{
hr = E_INVALIDARG;
}
else if (0 == lstrcmpiW(Name, L"$$test"))
{
*Value = 0xDeadCafeBabeBeefULL;
*TypeFlags = DEBUG_EXT_PVTYPE_IS_VALUE;
if (TypeId) *TypeId = 0; // Where are these types defined?
if (TypeModBase) *TypeModBase = 0;
hr = S_OK;
}
#if 0 // <-- ** Setting this to != 0 fixes the problem **
Client->Release(); // This does not feel right but it does seem to be required!
#endif
return hr;
}
EXTERN_C HRESULT CALLBACK DebugExtensionQueryValueNames(PDEBUG_CLIENT Client, ULONG Flags, OUT PWSTR Buffer, ULONG BufferChars, OUT PULONG BufferNeeded)
{
static const WCHAR pseregs[] = L"$$test\0";
if (BufferNeeded) *BufferNeeded = ARRAYSIZE(pseregs);
memcpy(Buffer, pseregs, min(sizeof(pseregs), BufferChars*sizeof(*Buffer)));
return ARRAYSIZE(pseregs) > BufferChars ? S_FALSE : S_OK;
}
EXTERN_C HRESULT CALLBACK DebugExtensionInitialize(OUT PULONG Version, OUT PULONG Flags)
{
*Version = DEBUG_EXTENSION_VERSION(1, 0), *Flags = 0;
return S_OK;
}
問題を再現すると、次のようになります。
0:000> $$ Press Ctrl+E to open a executable, I'm going to open WinVer.exe
0:000> .load c:\test\myext.dll
0:000> ?@$$test
Evaluate expression: -2401039830915039505 = deadcafe`babebeef
0:000> $$ Press Shift+F5 to stop debugging
0:000> $$ Press Ctrl+E and open a executable again, WinDbg will now print "Unable to deliver callback, 3131"
機能しているように見える回避策を思い付くことができましたが、QI も AddRef も行っていないインターフェイスをリリースする必要があるため、正しくないと感じます。私の最小限のテストでは、このハックがクラッシュすることはありませんでした.
私が知る限り、デバッグを停止して CDB でこのような新しい .exe を開くことはできないため、問題は WinDbg でのみ発生するようです。
私は何か間違ったことをしていますか、それとも DbgEng にバグがありますか?