Created
February 22, 2025 16:06
-
-
Save aliakseis/8ae52a9aa41f6f714a835c3852c30b1b to your computer and use it in GitHub Desktop.
MSVC exception stack trace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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