Skip to content

Instantly share code, notes, and snippets.

@aliakseis
Created February 22, 2025 16:06
Show Gist options
  • Save aliakseis/8ae52a9aa41f6f714a835c3852c30b1b to your computer and use it in GitHub Desktop.
Save aliakseis/8ae52a9aa41f6f714a835c3852c30b1b to your computer and use it in GitHub Desktop.
MSVC exception stack trace
LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* ExceptionInfo) {
// Filter out only C++ exceptions
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xE06D7363) { // MSVC C++ exception code
CONTEXT context = *ExceptionInfo->ContextRecord;
HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread();
SymInitialize(process, NULL, TRUE);
STACKFRAME64 stackFrame;
memset(&stackFrame, 0, sizeof(STACKFRAME64));
DWORD machineType = IMAGE_FILE_MACHINE_AMD64; // For x64 architecture
stackFrame.AddrPC.Offset = context.Rip;
stackFrame.AddrPC.Mode = AddrModeFlat;
stackFrame.AddrFrame.Offset = context.Rsp;
stackFrame.AddrFrame.Mode = AddrModeFlat;
stackFrame.AddrStack.Offset = context.Rsp;
stackFrame.AddrStack.Mode = AddrModeFlat;
char outputBuffer[4000];
size_t offset = 0;
offset += snprintf(outputBuffer + offset, sizeof(outputBuffer) - offset, "Stack trace:\n");
while (StackWalk64(machineType, process, thread, &stackFrame, &context, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL)) {
DWORD64 displacement = 0;
char symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO symbol = (PSYMBOL_INFO)symbolBuffer;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
if (SymFromAddr(process, stackFrame.AddrPC.Offset, &displacement, symbol)) {
offset += snprintf(outputBuffer + offset, sizeof(outputBuffer) - offset,
" %s - 0x%llX\n", symbol->Name, stackFrame.AddrPC.Offset);
}
else {
// If no symbol name is available, output the DLL name and offset
DWORD64 moduleBase = SymGetModuleBase64(process, stackFrame.AddrPC.Offset);
if (moduleBase) {
char moduleBuffer[MAX_PATH];
if (GetModuleFileNameA((HMODULE)moduleBase, moduleBuffer, MAX_PATH)) {
offset += snprintf(outputBuffer + offset, sizeof(outputBuffer) - offset,
" %s - 0x%llX\n", moduleBuffer, stackFrame.AddrPC.Offset - moduleBase);
}
}
}
if (offset >= sizeof(outputBuffer))
break;
}
OutputDebugStringA(outputBuffer);
SymCleanup(process);
}
return EXCEPTION_CONTINUE_SEARCH;
}
AddVectoredExceptionHandler(1, VectoredHandler);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment