'SymInitialize/SymFromAddr/SymGetLineFromAddr64 : how to get the correct stack frames for the process being debugged when running under a debugger?
From MSDN, https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-syminitialize
BOOL IMAGEAPI SymInitialize(
[in] HANDLE hProcess,
[in, optional] PCSTR UserSearchPath,
[in] BOOL fInvadeProcess
);
Parameters
[in] hProcess
A handle that identifies the caller. This value should be unique and nonzero, but need not
be a process handle. However, if you do use a process handle, be sure to use the correct
handle. If the application is a debugger, use the process handle for the process being
debugged. Do not use the handle returned by GetCurrentProcess when debugging another
process, because calling functions like SymLoadModuleEx can have unexpected results.
This parameter cannot be NULL.
When debugging under the debugger, GetCurrentProcess always returns -1, not the process handle for the process being debugged.
My question is then: how do I get the correct process handle for the process being debugged while running under a debugger?
I solved it by replaceing GetCurrentProces with OpenProcess as shown below:
//HANDLE process = GetCurrentProcess();
DWORD dwPid = GetCurrentProcessId();
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
I realized OpenProcess can give the right process handle being debugged, however still the code below fails to show the correct call stack trace under the debugger. So my real question is how to make the code print out the right call stack even running under a debugger.
void PrintStackTrace();
void *Allocate(std::size_t objSize)
{
PrintStackTrace();
}
int main()
{
Allocate(100);
}
// This function may be called at any point in time to get a print-out of the stack trace.
void PrintStackTrace()
{
tstringstream stream;
stream << _T("Started a stack trace") << std::endl;
void *stack[256];
//HANDLE process = GetCurrentProcess();
DWORD dwPid = GetCurrentProcessId();
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
SymInitialize(process, NULL, TRUE);
WORD numberOfFrames = CaptureStackBackTrace(0, 256, stack, NULL);
SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO) + 1024 * sizeof(TCHAR));
memset(symbol, 0, sizeof(SYMBOL_INFO) + 1024 * sizeof(TCHAR));
symbol->MaxNameLen = 1024;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
DWORD displacement;
IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
memset(line, 0, sizeof(IMAGEHLP_LINE64));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
for (int i = 0; i < numberOfFrames; i++)
{
DWORD64 address = (DWORD64)(stack[i]);
if (SymFromAddr(process, address, NULL, symbol))
{
if (SymGetLineFromAddr64(process, address, &displacement, line))
{
stream << _T("\tat ") << symbol->Name << _T(" in ") << line->FileName << _T(": line: ") << std::dec << line->LineNumber << _T(": address: ") << std::hex << symbol->Address << std::endl;
}
else
{
stream << _T("Error from SymGetLineFromAddr64: ") << std::hex << GetLastError() << std::endl;
stream << _T("\tat ") << symbol->Name << _T(": address: ") << std::hex << symbol->Address << std::endl;
}
}
else
{
stream << _T("Error from SymFromAddr: ") << std::hex << GetLastError() << std::endl;
}
}
tstring str = stream.str();
LPCTSTR message = str.c_str();
std::tcout << message;
free(symbol);
free(line);
}
[The output running in Release mode]
at Allocator::Allocate in e:\allocatorex.h : line: 1094 : address: 0x56E857C0
at Allocator::xAllocator::Allocate in e:\allocatorex.h : line: 2105 : address: 0x56E85C40
at PushFramework::IOBuffer::IOBuffer in e:\iobuffer.h : line: 65 : address: 0x56E97ED0
at PushFramework::PhysicalConnectionPool::createImpl in e:\physicalconnectionpool.h : line: 56 : address: 0x56E98D80
at PushFramework::ConnectionContextPool::initialize in e:\connectioncontextpool.h : line: 52 : address: 0x56E98480
at PushFramework::ServerImpl::start in e:\serverimpl.cpp : line: 289 : address: 0x56E99FE0
at tsServerOnline in e:\dllmain.cpp : line: 15156 : address: 0x56E8DB90
at DllMain in e:\dllmain.cpp : line: 12831 : address: 0x56E8B7B0
at dllmain_dispatch in d:\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp : line: 200 : address: 0x56EA178B
at _DllMainCRTStartup in d:\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp : line: 253 : address: 0x56EA18BC
Error from SymGetLineFromAddr64: 0x1E7
at RtlIpv6AddressToStringA : address: 0x77A227B0
Error from SymGetLineFromAddr64: 0x1E7
at RtlActivateActivationContextUnsafeFast : address: 0x779FDC40
Error from SymGetLineFromAddr64: 0x1E7
at RtlEqualUnicodeString : address: 0x77A01280
Error from SymGetLineFromAddr64: 0x1E7
at RtlEqualUnicodeString : address: 0x77A01280
Error from SymGetLineFromAddr64: 0x1E7
at RtlEqualUnicodeString : address: 0x77A01280
Error from SymGetLineFromAddr64: 0x1E7
at RtlCaptureStackContext : address: 0x77A38C40
Error from SymGetLineFromAddr64: 0x1E7
at LdrInitializeThunk : address: 0x77A162F0
Error from SymGetLineFromAddr64: 0x1E7
at LdrInitializeThunk : address: 0x77A162F0
[The output running in Debug mode]
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymFromAddr: 0x1E7
Error from SymGetLineFromAddr64: 0x1E7
at RtlIpv6AddressToStringA : address: 0x77A227B0
Error from SymGetLineFromAddr64: 0x1E7
at RtlActivateActivationContextUnsafeFast : address: 0x779FDC40
Error from SymGetLineFromAddr64: 0x1E7
at RtlEqualUnicodeString : address: 0x77A01280
Error from SymGetLineFromAddr64: 0x1E7
at RtlEqualUnicodeString : address: 0x77A01280
Error from SymGetLineFromAddr64: 0x1E7
at RtlEqualUnicodeString : address: 0x77A01280
Error from SymGetLineFromAddr64: 0x1E7
at RtlCaptureStackContext : address: 0x77A38C40
Error from SymGetLineFromAddr64: 0x1E7
at LdrInitializeThunk : address: 0x77A162F0
Error from SymGetLineFromAddr64: 0x1E7
at LdrInitializeThunk : address: 0x77A162F0
How can I make the output from Debug mode look the same as the Release mode?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
