HRESULT
DumpMixedCallStack(
PDEBUG_CLIENT pClient,
PDEBUG_CONTROL pControl)
{
// We can not use LoadLibrary Win32 API to load SOS.
// To load an extension library (or to obtain a handle for an already loaded extension library), use AddExtension.
// Son of strike is written as a DbgEng Extension, since it exports DebugExtensionInitialize.
// SOS exports 4 extension function with its prefix as "_EFN_".
// 1 44 00024960 _EFN_GetManagedExcepStack
// 2 45 00022190 _EFN_GetManagedObjectFieldInfo
// 3 46 00022070 _EFN_GetManagedObjectName
// 4 47 00021FC0 _EFN_StackTrace
HRESULT hr = S_OK;
// Load extension library
ULONG64 pHandle;
hr = pControl->AddExtension("sos", 0, &pHandle);
if(FAILED(hr))
{
goto cleanup;
}
typedef HRESULT (CALLBACK *FP_EFN_StackTrace)(PDEBUG_CLIENT Client, WCHAR wszTextOut[], UINT *puiTextLength, LPVOID pTransitionContexts, UINT *puiTransitionContextCount, UINT uiSizeOfContext, DWORD Flags);
FP_EFN_StackTrace fp_efn_stacktrace = NULL;
hr = pControl->GetExtensionFunction(pHandle, "StackTrace", (FARPROC *)&fp_efn_stacktrace);
if (SUCCEEDED(hr) && fp_efn_stacktrace != NULL)
{
UINT puiTextLength;
UINT puiTransitionContextCount;
hr = fp_efn_stacktrace(pClient, NULL, &puiTextLength,
NULL, &puiTransitionContextCount, sizeof(CONTEXT), SOS_STACKTRACE_SHOWADDRESSES);
WCHAR *stacksBuffer = new WCHAR[puiTextLength];
CONTEXT* contextBuffer = new CONTEXT[puiTransitionContextCount];
// Contexts for transition…
hr = fp_efn_stacktrace(
pClient, stacksBuffer, &puiTextLength, contextBuffer,
&puiTransitionContextCount, sizeof(CONTEXT), SOS_STACKTRACE_SHOWADDRESSES); // print out esp and ebp.
wprintf(L"%s\n", stacksBuffer);
if (stacksBuffer != NULL)
{
delete[] stacksBuffer;
}
if (contextBuffer != NULL)
{
delete[] contextBuffer;
}
}
else
goto cleanup;
// Unload extension library
hr = pControl->RemoveExtension(pHandle);
if(FAILED(hr))
{
goto cleanup;
}
cleanup:
return hr;
}
Austin.D