diff options
author | Ray Molenkamp <github@lazydodo.com> | 2020-05-08 18:39:41 +0300 |
---|---|---|
committer | Ray Molenkamp <github@lazydodo.com> | 2020-05-08 18:39:41 +0300 |
commit | cc1fb9d1779c35edef0e5a7771bd7e35984561fd (patch) | |
tree | 15c1e14b598fa4fc9775e3af4455f0004ca9fa3d /source/blender/blenlib/intern/system_win32.c | |
parent | fc0842593f0c5892bdb6b0cc95df2aeb3e449f5b (diff) |
Windows: Fix BLI_assert backtrace.
With the recent backtrace overhaul, the fact that BLI_assert calls
BLI_system_backtrace slipped somehow trough the cracks, causing
issues for debug builds.
This change allows BLI_system_backtrace to run again without having
an exception record.
Also minor improvements to the comments.
Diffstat (limited to 'source/blender/blenlib/intern/system_win32.c')
-rw-r--r-- | source/blender/blenlib/intern/system_win32.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/source/blender/blenlib/intern/system_win32.c b/source/blender/blenlib/intern/system_win32.c index 4fea47386ea..115432bc7d5 100644 --- a/source/blender/blenlib/intern/system_win32.c +++ b/source/blender/blenlib/intern/system_win32.c @@ -28,7 +28,7 @@ #include "MEM_guardedalloc.h" -static EXCEPTION_POINTERS *current_exception; +static EXCEPTION_POINTERS *current_exception = NULL; static const char *bli_windows_get_exception_description(const DWORD exceptioncode) { @@ -212,20 +212,25 @@ static bool BLI_windows_system_backtrace_run_trace(FILE *fp, HANDLE hThread, PCO return result; } -static void bli_windows_system_backtrace_stack_thread(FILE *fp, HANDLE hThread) +static bool bli_windows_system_backtrace_stack_thread(FILE *fp, HANDLE hThread) { - if (hThread != GetCurrentThread()) { - SuspendThread(hThread); - } - CONTEXT context; + CONTEXT context = {0}; context.ContextFlags = CONTEXT_ALL; - if (!GetThreadContext(hThread, &context)) { - fprintf(fp, "Cannot get thread context : 0x0%.8x\n", GetLastError()); - } - BLI_windows_system_backtrace_run_trace(fp, hThread, &context); + /* GetThreadContext requires the thread to be in a suspended state, which is problematic for the + * currently running thread, RtlCaptureContext is used as an alternative to sidestep this */ if (hThread != GetCurrentThread()) { + SuspendThread(hThread); + bool success = GetThreadContext(hThread, &context); ResumeThread(hThread); + if (!success) { + fprintf(fp, "Cannot get thread context : 0x0%.8x\n", GetLastError()); + return false; + } + } + else { + RtlCaptureContext(&context); } + return BLI_windows_system_backtrace_run_trace(fp, hThread, &context); } static void bli_windows_system_backtrace_modules(FILE *fp) @@ -287,8 +292,16 @@ static void bli_windows_system_backtrace_threads(FILE *fp) static bool BLI_windows_system_backtrace_stack(FILE *fp) { fprintf(fp, "Stack trace:\n"); - CONTEXT TempContext = *current_exception->ContextRecord; - return BLI_windows_system_backtrace_run_trace(fp, GetCurrentThread(), &TempContext); + /* If we are handling an exception use the context record from that. */ + if (current_exception) { + /* The back trace code will write to the context record, to protect the original record from + * modifications give the backtrace a copy to work on. */ + CONTEXT TempContext = *current_exception->ContextRecord; + return BLI_windows_system_backtrace_run_trace(fp, GetCurrentThread(), &TempContext); + } + else { + return bli_windows_system_backtrace_stack_thread(fp, GetCurrentThread()); + } } static bool bli_private_symbols_loaded() @@ -350,7 +363,9 @@ void BLI_system_backtrace(FILE *fp) { SymInitialize(GetCurrentProcess(), NULL, TRUE); bli_load_symbols(); - bli_windows_system_backtrace_exception_record(fp, current_exception->ExceptionRecord); + if (current_exception) { + bli_windows_system_backtrace_exception_record(fp, current_exception->ExceptionRecord); + } if (BLI_windows_system_backtrace_stack(fp)) { /* When the blender symbols are missing the stack traces will be unreliable * so only run if the previous step completed successfully. */ @@ -363,16 +378,18 @@ void BLI_system_backtrace(FILE *fp) void BLI_windows_handle_exception(EXCEPTION_POINTERS *exception) { current_exception = exception; - fprintf(stderr, - "Error : %s\n", - bli_windows_get_exception_description(exception->ExceptionRecord->ExceptionCode)); - fflush(stderr); - - LPVOID address = exception->ExceptionRecord->ExceptionAddress; - fprintf(stderr, "Address : 0x%p\n", address); - - CHAR modulename[MAX_PATH]; - bli_windows_get_module_name(address, modulename, sizeof(modulename)); - fprintf(stderr, "Module : %s\n", modulename); + if (current_exception) { + fprintf(stderr, + "Error : %s\n", + bli_windows_get_exception_description(exception->ExceptionRecord->ExceptionCode)); + fflush(stderr); + + LPVOID address = exception->ExceptionRecord->ExceptionAddress; + fprintf(stderr, "Address : 0x%p\n", address); + + CHAR modulename[MAX_PATH]; + bli_windows_get_module_name(address, modulename, sizeof(modulename)); + fprintf(stderr, "Module : %s\n", modulename); + } fflush(stderr); } |