I'm implementing DebugExtensionProvideValue in my extension so I can provide custom pseudo-registers. It works perfectly in CDB and it works fine initially in WinDbg but after stopping debugging and opening a new executable something happens and WinDbg ends up in a weird unusable state.
WinDbg prints "Unable to deliver callback, 3131" to the command window when you trigger the problem and after that all output is printed twice in the command window!
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!
I'm not including DebugExtensionQueryValueNames and DebugExtensionInitialize here because they are pretty boilerplate but you can see them @ http://stackoverflow.com/q/37417335/3501
Reproducing the issue looks something like this:
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
Unable to deliver callback, 3131
If I release the IDebugClient passed to me in DebugExtensionProvideValue then the problem goes away but it feels so wrong and breaks all kinds of COM rules. I have tested multiple WinDbg versions, both 32 and 64-bit and they all act the same, no problems with the hack and the callback error without it.
Am I doing something wrong or is there a bug in DbgEng?