fixes issues with minidump on win32

minidump did not have proper exception record passed in, so it did not
contain actual issue of the unhandled exception. Also stack walking
before was mutating registers in exception CONTEXT, this means that
minidump did not have proper call stack anymore. Now code make a local
copy of CONTEXT for stack walking.
This commit is contained in:
Martins Mozeiko
2026-02-03 15:15:13 -08:00
committed by Nikita
parent f330bde8aa
commit a13afb441e
3 changed files with 41 additions and 24 deletions
+40 -21
View File
@@ -1521,7 +1521,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
{ {
HANDLE process = GetCurrentProcess(); HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread(); HANDLE thread = GetCurrentThread();
CONTEXT* context = exception_ptrs->ContextRecord; CONTEXT context = *exception_ptrs->ContextRecord;
WCHAR module_path[MAX_PATH]; WCHAR module_path[MAX_PATH];
GetModuleFileNameW(NULL, module_path, ArrayCount(module_path)); GetModuleFileNameW(NULL, module_path, ArrayCount(module_path));
@@ -1552,19 +1552,19 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
DWORD image_type; DWORD image_type;
#if defined(_M_AMD64) #if defined(_M_AMD64)
image_type = IMAGE_FILE_MACHINE_AMD64; image_type = IMAGE_FILE_MACHINE_AMD64;
frame.AddrPC.Offset = context->Rip; frame.AddrPC.Offset = context.Rip;
frame.AddrPC.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Rbp; frame.AddrFrame.Offset = context.Rbp;
frame.AddrFrame.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Rsp; frame.AddrStack.Offset = context.Rsp;
frame.AddrStack.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat;
#elif defined(_M_ARM64) #elif defined(_M_ARM64)
image_type = IMAGE_FILE_MACHINE_ARM64; image_type = IMAGE_FILE_MACHINE_ARM64;
frame.AddrPC.Offset = context->Pc; frame.AddrPC.Offset = context.Pc;
frame.AddrPC.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Fp; frame.AddrFrame.Offset = context.Fp;
frame.AddrFrame.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Sp; frame.AddrStack.Offset = context.Sp;
frame.AddrStack.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat;
#else #else
# error Arch not supported! # error Arch not supported!
@@ -1594,11 +1594,11 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
frame.AddrPC.Offset = *(DWORD64*)frame.AddrStack.Offset - 1; frame.AddrPC.Offset = *(DWORD64*)frame.AddrStack.Offset - 1;
frame.AddrStack.Offset += sizeof(void*); frame.AddrStack.Offset += sizeof(void*);
#if defined(_M_AMD64) #if defined(_M_AMD64)
context->Rip = frame.AddrPC.Offset; context.Rip = frame.AddrPC.Offset;
context->Rsp = frame.AddrStack.Offset; context.Rsp = frame.AddrStack.Offset;
#elif defined(_M_ARM64) #elif defined(_M_ARM64)
context->Pc = frame.AddrPC.Offset; context.Pc = frame.AddrPC.Offset;
context->Sp = frame.AddrStack.Offset; context.Sp = frame.AddrStack.Offset;
#endif #endif
} }
@@ -1615,7 +1615,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
break; break;
} }
if(!dbg_StackWalk64(image_type, process, thread, &frame, context, 0, dbg_SymFunctionTableAccess64, dbg_SymGetModuleBase64, 0)) if(!dbg_StackWalk64(image_type, process, thread, &frame, &context, 0, dbg_SymFunctionTableAccess64, dbg_SymGetModuleBase64, 0))
{ {
break; break;
} }
@@ -1692,15 +1692,33 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
if(dbg_MiniDumpWriteDump && generate_crash_dump) if(dbg_MiniDumpWriteDump && generate_crash_dump)
{ {
WCHAR desktop_path[512] = {0}; WCHAR dump_file_path[MAX_PATH] = {0};
SHGetFolderPathW(0, CSIDL_DESKTOP, 0, 0, desktop_path); SHGetFolderPathW(0, CSIDL_DESKTOP, 0, 0, dump_file_path);
WCHAR dump_file_path[512] = {0}; PathAppendW(dump_file_path, L"raddbg_crash_dump.dmp");
wnsprintfW(dump_file_path, ArrayCount(dump_file_path), L"%s\\raddbg_crash_dump.dmp", desktop_path); HANDLE file = CreateFileW(dump_file_path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0}; if (file != INVALID_HANDLE_VALUE)
HANDLE file = CreateFileW(dump_file_path, GENERIC_WRITE, 0, &security_attributes, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); {
BOOL dump_successful = dbg_MiniDumpWriteDump(GetCurrentProcess(), os_get_process_info()->pid, file, MiniDumpNormal, 0, 0, 0); MINIDUMP_EXCEPTION_INFORMATION info = {0};
CloseHandle(file); info.ThreadId = GetCurrentThreadId();
(void)dump_successful; info.ExceptionPointers = exception_ptrs;
info.ClientPointers = FALSE;
BOOL dump_successful = dbg_MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpNormal, &info, 0, 0);
CloseHandle(file);
if (dump_successful)
{
#if !BUILD_CONSOLE_INTERFACE
// opens explorer and selects file
SFGAOF flags = 0;
PIDLIST_ABSOLUTE list = 0;
if (SUCCEEDED(SHParseDisplayName(dump_file_path, NULL, &list, 0, &flags)))
{
SHOpenFolderAndSelectItems(list, 0, NULL, 0);
CoTaskMemFree(list);
}
#endif
}
}
} }
ExitProcess(1); ExitProcess(1);
@@ -1890,6 +1908,7 @@ int wmain(int argc, WCHAR **argv)
#else #else
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{ {
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
w32_entry_point_caller(__argc, __wargv); w32_entry_point_caller(__argc, __wargv);
return 0; return 0;
} }
+1 -1
View File
@@ -16,7 +16,7 @@
#include <Shlobj.h> #include <Shlobj.h>
#include <processthreadsapi.h> #include <processthreadsapi.h>
#pragma comment(lib, "user32") #pragma comment(lib, "user32")
#pragma comment(lib, "winmm") #pragma comment(lib, "ole32")
#pragma comment(lib, "shell32") #pragma comment(lib, "shell32")
#pragma comment(lib, "advapi32") #pragma comment(lib, "advapi32")
#pragma comment(lib, "rpcrt4") #pragma comment(lib, "rpcrt4")
-2
View File
@@ -13,8 +13,6 @@
#pragma comment(lib, "gdi32") #pragma comment(lib, "gdi32")
#pragma comment(lib, "dwmapi") #pragma comment(lib, "dwmapi")
#pragma comment(lib, "UxTheme") #pragma comment(lib, "UxTheme")
#pragma comment(lib, "ole32")
#pragma comment(lib, "user32")
#pragma comment(lib, "comdlg32") #pragma comment(lib, "comdlg32")
#ifndef WM_NCUAHDRAWCAPTION #ifndef WM_NCUAHDRAWCAPTION
#define WM_NCUAHDRAWCAPTION (0x00AE) #define WM_NCUAHDRAWCAPTION (0x00AE)