mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-27 13:53:37 +08:00
sdlprocdump: store context and exception record in minidump
This commit is contained in:
parent
0fa74d8aa8
commit
be43dec798
@ -181,10 +181,11 @@ static const char *get_simple_basename(const char *path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
static void write_minidump(const char *child_file_path, const LPPROCESS_INFORMATION process_information, DWORD dwThreadId) {
|
||||
static void write_minidump(const char *child_file_path, const LPPROCESS_INFORMATION process_information, DWORD dwThreadId, PEXCEPTION_RECORD exception_record, PCONTEXT context) {
|
||||
BOOL success;
|
||||
char dump_file_path[MAX_PATH];
|
||||
char child_file_name[64];
|
||||
EXCEPTION_POINTERS exception_pointers;
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
HMODULE dbghelp_module = NULL;
|
||||
MINIDUMP_EXCEPTION_INFORMATION minidump_exception_information;
|
||||
@ -221,8 +222,11 @@ static void write_minidump(const char *child_file_path, const LPPROCESS_INFORMAT
|
||||
printf_windows_message("Failed to open file for minidump");
|
||||
goto post_dump;
|
||||
}
|
||||
memset(&exception_pointers, 0, sizeof(exception_pointers));
|
||||
exception_pointers.ContextRecord = context;
|
||||
exception_pointers.ExceptionRecord = exception_record;
|
||||
minidump_exception_information.ClientPointers = FALSE;
|
||||
minidump_exception_information.ExceptionPointers = FALSE;
|
||||
minidump_exception_information.ExceptionPointers = &exception_pointers;
|
||||
minidump_exception_information.ThreadId = dwThreadId;
|
||||
success = dyn_dbghelp.pMiniDumpWriteDump(
|
||||
process_information->hProcess, /* HANDLE hProcess */
|
||||
@ -244,11 +248,13 @@ post_dump:
|
||||
}
|
||||
}
|
||||
|
||||
static void print_stacktrace(const LPPROCESS_INFORMATION process_information, LPVOID address) {
|
||||
static void print_stacktrace(const LPPROCESS_INFORMATION process_information, PCONTEXT context, LPVOID address) {
|
||||
STACKFRAME64 stack_frame;
|
||||
CONTEXT context;
|
||||
HANDLE thread_handle = NULL;
|
||||
|
||||
if (!context) {
|
||||
printf_message("Cannot create a stacktrace without a context");
|
||||
return;
|
||||
}
|
||||
if (!dyn_dbghelp.pStackWalk64) {
|
||||
printf_message("Cannot find StackWalk64 in dbghelp.dll: no stacktrace");
|
||||
return;
|
||||
@ -274,19 +280,6 @@ static void print_stacktrace(const LPPROCESS_INFORMATION process_information, LP
|
||||
return;
|
||||
}
|
||||
|
||||
thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, process_information->dwThreadId);
|
||||
if (!thread_handle) {
|
||||
printf_windows_message("OpenThread failed: no stacktrace");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.ContextFlags = CONTEXT_ALL;
|
||||
if (!GetThreadContext(thread_handle, &context)) {
|
||||
printf_windows_message("GetThreadContext failed: no stacktrace");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!dyn_dbghelp.pSymRefreshModuleList || !dyn_dbghelp.pSymRefreshModuleList(process_information->hProcess)) {
|
||||
printf_windows_message("SymRefreshModuleList failed: maybe no stacktrace");
|
||||
}
|
||||
@ -299,24 +292,24 @@ static void print_stacktrace(const LPPROCESS_INFORMATION process_information, LP
|
||||
|
||||
#if defined(SDLPROCDUMP_CPU_X86)
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_I386;
|
||||
stack_frame.AddrFrame.Offset = context.Ebp;
|
||||
stack_frame.AddrStack.Offset = context.Esp;
|
||||
stack_frame.AddrPC.Offset = context.Eip;
|
||||
stack_frame.AddrFrame.Offset = context->Ebp;
|
||||
stack_frame.AddrStack.Offset = context->Esp;
|
||||
stack_frame.AddrPC.Offset = context->Eip;
|
||||
#elif defined(SDLPROCDUMP_CPU_X64)
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_AMD64;
|
||||
stack_frame.AddrFrame.Offset = context.Rbp;
|
||||
stack_frame.AddrStack.Offset = context.Rsp;
|
||||
stack_frame.AddrPC.Offset = context.Rip;
|
||||
stack_frame.AddrFrame.Offset = context->Rbp;
|
||||
stack_frame.AddrStack.Offset = context->Rsp;
|
||||
stack_frame.AddrPC.Offset = context->Rip;
|
||||
#elif defined(SDLPROCDUMP_CPU_ARM32)
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_ARM;
|
||||
stack_frame.AddrFrame.Offset = context.Lr;
|
||||
stack_frame.AddrStack.Offset = context.Sp;
|
||||
stack_frame.AddrPC.Offset = context.Pc;
|
||||
stack_frame.AddrFrame.Offset = context->Lr;
|
||||
stack_frame.AddrStack.Offset = context->Sp;
|
||||
stack_frame.AddrPC.Offset = context->Pc;
|
||||
#elif defined(SDLPROCDUMP_CPU_ARM64)
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_ARM64;
|
||||
stack_frame.AddrFrame.Offset = context.Fp;
|
||||
stack_frame.AddrStack.Offset = context.Sp;
|
||||
stack_frame.AddrPC.Offset = context.Pc;
|
||||
stack_frame.AddrFrame.Offset = context->Fp;
|
||||
stack_frame.AddrStack.Offset = context->Sp;
|
||||
stack_frame.AddrPC.Offset = context->Pc;
|
||||
#endif
|
||||
while (dyn_dbghelp.pStackWalk64(machine_type, /* DWORD MachineType */
|
||||
process_information->hProcess, /* HANDLE hProcess */
|
||||
@ -374,12 +367,26 @@ static void print_stacktrace(const LPPROCESS_INFORMATION process_information, LP
|
||||
}
|
||||
printf_message("%s!%s+0x%x %s %s", image_file_name, symbol_name, dwDisplacement, file_name, line_number);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (thread_handle) {
|
||||
CloseHandle(thread_handle);
|
||||
static PCONTEXT FillInThreadContext(LPPROCESS_INFORMATION process_information, PCONTEXT context_buffer) {
|
||||
HANDLE thread_handle = NULL;
|
||||
|
||||
thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, process_information->dwThreadId);
|
||||
if (!thread_handle) {
|
||||
printf_windows_message("OpenThread failed: no stacktrace");
|
||||
return NULL;
|
||||
}
|
||||
return;
|
||||
|
||||
memset(context_buffer, 0, sizeof(*context_buffer));
|
||||
context_buffer->ContextFlags = CONTEXT_ALL;
|
||||
if (!GetThreadContext(thread_handle, context_buffer)) {
|
||||
printf_windows_message("GetThreadContext failed: no stacktrace");
|
||||
CloseHandle(thread_handle);
|
||||
return NULL;
|
||||
}
|
||||
CloseHandle(thread_handle);
|
||||
return context_buffer;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@ -454,6 +461,9 @@ int main(int argc, char *argv[]) {
|
||||
switch (event.dwDebugEventCode) {
|
||||
case EXCEPTION_DEBUG_EVENT:
|
||||
if (IsFatalExceptionCode(event.u.Exception.ExceptionRecord.ExceptionCode) || (event.u.Exception.ExceptionRecord.ExceptionFlags & EXCEPTION_NONCONTINUABLE)) {
|
||||
CONTEXT context_buffer;
|
||||
PCONTEXT context;
|
||||
|
||||
printf_message("EXCEPTION_DEBUG_EVENT");
|
||||
printf_message(" ExceptionCode: 0x%08lx (%s)",
|
||||
event.u.Exception.ExceptionRecord.ExceptionCode,
|
||||
@ -463,10 +473,12 @@ int main(int argc, char *argv[]) {
|
||||
printf_message(" ExceptionAddress: 0x%08lx",
|
||||
event.u.Exception.ExceptionRecord.ExceptionAddress);
|
||||
printf_message(" (Non-continuable exception debug event)");
|
||||
write_minidump(argv[1], &process_information, event.dwThreadId);
|
||||
|
||||
context = FillInThreadContext(&process_information, &context_buffer);
|
||||
write_minidump(argv[1], &process_information, event.dwThreadId, &event.u.Exception.ExceptionRecord, context);
|
||||
printf_message("");
|
||||
#ifdef SDLPROCDUMP_PRINTSTACK
|
||||
print_stacktrace(&process_information, event.u.Exception.ExceptionRecord.ExceptionAddress);
|
||||
print_stacktrace(&process_information, event.u.Exception.ExceptionRecord.ExceptionAddress, context);
|
||||
#else
|
||||
printf_message("No support for printing stacktrack for current architecture");
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user