diff options
author | Ray Molenkamp <github@lazydodo.com> | 2020-05-01 16:37:48 +0300 |
---|---|---|
committer | Ray Molenkamp <github@lazydodo.com> | 2020-05-01 16:37:48 +0300 |
commit | b523911e860e6602cf4dc3df67a405b469f22b74 (patch) | |
tree | f0942de23753788f247ba1a35c6de8e4047866de /source/creator | |
parent | 4cc8123377b1502e028a8f9e6132b78e46e0520f (diff) |
Windows: Support backtraces on release builds.
This diff add supports for crash logs on windows for
release builds. This can be toggled on/off with the
`WITH_WINDOWS_PDB` cmake option. by default it is on.
Things to take into consideration:
Release builds are hightly optimized and the resulting
backtraces can be wrong/misleading, take the backtrace
as a general area where the problem resides rather than
an exact location.
By default we ship a minimized symbol file that can only
resolve the function names. This was chosen to strike
a balance between growth in size of the download vs
functionality gained. If more detailed information is
required such as source file + line number information
a full pdb can be shipped by setting `WITH_WINDOWS_STRIPPED_PDB`
to off.
Differential Revision: https://developer.blender.org/D7520
Reviewed by: brecht
Diffstat (limited to 'source/creator')
-rw-r--r-- | source/creator/CMakeLists.txt | 25 | ||||
-rw-r--r-- | source/creator/creator_signals.c | 102 |
2 files changed, 40 insertions, 87 deletions
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 4b51f9738b3..a634618ee94 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -687,6 +687,17 @@ elseif(WIN32) ) endif() + if(WITH_WINDOWS_PDB) + if(WITH_WINDOWS_STRIPPED_PDB) + # Icky hack for older cmake from https://stackoverflow.com/a/21198501 + # $<CONFIG> will work in newer cmake but the version currently (3.12) + # on the buildbot does not support this endavour. + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/blender_public.pdb DESTINATION . RENAME blender.pdb) + else() + install(FILES $<TARGET_PDB_FILE:blender> DESTINATION . RENAME blender.pdb) + endif() + endif() + if(WITH_PYTHON) string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) @@ -1085,6 +1096,20 @@ endif() # the use of vcpkg if(WIN32) set_target_properties(blender PROPERTIES VS_GLOBAL_VcpkgEnabled "false") + set_target_properties(blender PROPERTIES + PDB_NAME "blender_private" + PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>") + if (WITH_WINDOWS_PDB AND WITH_WINDOWS_STRIPPED_PDB) + # This is slightly messy, but single target generators like ninja will not have the + # CMAKE_CFG_INTDIR variable and multitarget generators like msbuild will not have + # CMAKE_BUILD_TYPE. This can be simplified by target_link_options and the $<CONFIG> + # generator expression in newer cmake (2.13+) but until that time this fill have suffice. + if(CMAKE_BUILD_TYPE) + set_property(TARGET blender APPEND PROPERTY LINK_FLAGS " /PDBSTRIPPED:${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/blender_public.pdb") + else() + set_property(TARGET blender APPEND PROPERTY LINK_FLAGS " /PDBSTRIPPED:${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/blender_public.pdb") + endif() + endif() endif() # ----------------------------------------------------------------------------- diff --git a/source/creator/creator_signals.c b/source/creator/creator_signals.c index 7f7a03f0465..0ffa374a0ff 100644 --- a/source/creator/creator_signals.c +++ b/source/creator/creator_signals.c @@ -190,97 +190,25 @@ static void sig_handle_crash(int signum) } # ifdef WIN32 -LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo) +extern LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo) { - switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { - case EXCEPTION_ACCESS_VIOLATION: - fputs("Error : EXCEPTION_ACCESS_VIOLATION\n", stderr); - break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - fputs("Error : EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr); - break; - case EXCEPTION_BREAKPOINT: - fputs("Error : EXCEPTION_BREAKPOINT\n", stderr); - break; - case EXCEPTION_DATATYPE_MISALIGNMENT: - fputs("Error : EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr); - break; - case EXCEPTION_FLT_DENORMAL_OPERAND: - fputs("Error : EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr); - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - fputs("Error : EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr); - break; - case EXCEPTION_FLT_INEXACT_RESULT: - fputs("Error : EXCEPTION_FLT_INEXACT_RESULT\n", stderr); - break; - case EXCEPTION_FLT_INVALID_OPERATION: - fputs("Error : EXCEPTION_FLT_INVALID_OPERATION\n", stderr); - break; - case EXCEPTION_FLT_OVERFLOW: - fputs("Error : EXCEPTION_FLT_OVERFLOW\n", stderr); - break; - case EXCEPTION_FLT_STACK_CHECK: - fputs("Error : EXCEPTION_FLT_STACK_CHECK\n", stderr); - break; - case EXCEPTION_FLT_UNDERFLOW: - fputs("Error : EXCEPTION_FLT_UNDERFLOW\n", stderr); - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - fputs("Error : EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr); - break; - case EXCEPTION_IN_PAGE_ERROR: - fputs("Error : EXCEPTION_IN_PAGE_ERROR\n", stderr); - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - fputs("Error : EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr); - break; - case EXCEPTION_INT_OVERFLOW: - fputs("Error : EXCEPTION_INT_OVERFLOW\n", stderr); - break; - case EXCEPTION_INVALID_DISPOSITION: - fputs("Error : EXCEPTION_INVALID_DISPOSITION\n", stderr); - break; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - fputs("Error : EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr); - break; - case EXCEPTION_PRIV_INSTRUCTION: - fputs("Error : EXCEPTION_PRIV_INSTRUCTION\n", stderr); - break; - case EXCEPTION_SINGLE_STEP: - fputs("Error : EXCEPTION_SINGLE_STEP\n", stderr); - break; - case EXCEPTION_STACK_OVERFLOW: - fputs("Error : EXCEPTION_STACK_OVERFLOW\n", stderr); - break; - default: - fputs("Error : Unrecognized Exception\n", stderr); - break; - } - - fflush(stderr); - - /* If this is a stack overflow then we can't walk the stack, so just show + /* If this is a stack overflow then we can't walk the stack, so just try to show * where the error happened */ - if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { - HMODULE mod; - CHAR modulename[MAX_PATH]; - LPVOID address = ExceptionInfo->ExceptionRecord->ExceptionAddress; - - fprintf(stderr, "Address : 0x%p\n", address); - if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, address, &mod)) { - if (GetModuleFileName(mod, modulename, MAX_PATH)) { - fprintf(stderr, "Module : %s\n", modulename); + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { + HMODULE mod; + CHAR modulename[MAX_PATH]; + LPVOID address = ExceptionInfo->ExceptionRecord->ExceptionAddress; + fprintf(stderr, "Error : EXCEPTION_STACK_OVERFLOW\n"); + fprintf(stderr, "Address : 0x%p\n", address); + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, address, &mod)) { + if (GetModuleFileName(mod, modulename, MAX_PATH)) { + fprintf(stderr, "Module : %s\n", modulename); + } } - } - - fflush(stderr); - -# ifdef NDEBUG - TerminateProcess(GetCurrentProcess(), SIGSEGV); -# else + } + else { + BLI_windows_handle_exception(ExceptionInfo); sig_handle_crash(SIGSEGV); -# endif } return EXCEPTION_EXECUTE_HANDLER; |