From 431c5a101f7f3806aea67d234177bd5de57aaf9f Mon Sep 17 00:00:00 2001 From: goeiecool9999 <7033575+goeiecool9999@users.noreply.github.com> Date: Mon, 10 Oct 2022 02:35:04 +0200 Subject: [PATCH] Linux: Print demangled symbols on backtrace (#312) --- src/CMakeLists.txt | 4 ++ src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h | 6 +-- .../ExceptionHandler_posix.cpp | 51 +++++++++++++++++-- src/Common/precompiled.h | 6 +++ 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 024432d0..32d6fe60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,10 @@ elseif(UNIX) add_compile_options(-Wno-ambiguous-reversed-operator) endif() + if(NOT APPLE) + add_link_options(-rdynamic) + endif() + add_compile_options(-Wno-multichar -Wno-invalid-offsetof -Wno-switch -Wno-ignored-attributes -Wno-deprecated-enum-enum-conversion) endif() diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h index c1f2dee6..437f00b1 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h @@ -15,9 +15,9 @@ extern bool g_vulkan_available; #endif #ifdef VKFUNC_DEFINE - #define VKFUNC(__FUNC__) PFN_##__FUNC__ __FUNC__ = nullptr - #define VKFUNC_INSTANCE(__FUNC__) PFN_##__FUNC__ __FUNC__ = nullptr - #define VKFUNC_DEVICE(__FUNC__) PFN_##__FUNC__ __FUNC__ = nullptr + #define VKFUNC(__FUNC__) NOEXPORT PFN_##__FUNC__ __FUNC__ = nullptr + #define VKFUNC_INSTANCE(__FUNC__) NOEXPORT PFN_##__FUNC__ __FUNC__ = nullptr + #define VKFUNC_DEVICE(__FUNC__) NOEXPORT PFN_##__FUNC__ __FUNC__ = nullptr #else #if defined(VKFUNC_INIT) #if BOOST_OS_WINDOWS diff --git a/src/Common/ExceptionHandler/ExceptionHandler_posix.cpp b/src/Common/ExceptionHandler/ExceptionHandler_posix.cpp index e2ea3d33..86d83bb3 100644 --- a/src/Common/ExceptionHandler/ExceptionHandler_posix.cpp +++ b/src/Common/ExceptionHandler/ExceptionHandler_posix.cpp @@ -1,9 +1,43 @@ #include #include #include +#include #include "config/CemuConfig.h" +void demangleAndPrintBacktrace(char** backtrace, size_t size) +{ + for (char** i = backtrace; i < backtrace + size; i++) + { + std::string traceLine{*i}; + size_t parenthesesOpen = traceLine.find_last_of('('); + size_t parenthesesClose = traceLine.find_last_of(')'); + size_t offsetPlus = traceLine.find_last_of('+'); + if (!parenthesesOpen || !parenthesesClose || !offsetPlus || + offsetPlus < parenthesesOpen || offsetPlus > parenthesesClose) + { + // something unexpected was read. fall back to default string + std::cerr << traceLine << std::endl; + continue; + } + + std::string symbolName = traceLine.substr(parenthesesOpen+1,offsetPlus-parenthesesOpen-1); + int status = -1; + char* demangled = abi::__cxa_demangle(symbolName.c_str(), nullptr, nullptr, &status); + if (demangled) + { + std::cerr << traceLine.substr(0, parenthesesOpen+1); + std::cerr << demangled; + std::cerr << traceLine.substr(offsetPlus) << std::endl; + free(demangled); + } + else + { + std::cerr << traceLine << std::endl; + } + } +} + // handle signals that would dump core, print stacktrace and then dump depending on config void handlerDumpingSignal(int sig) { @@ -18,15 +52,26 @@ void handlerDumpingSignal(int sig) printf("Unknown core dumping signal!\n"); } - void *array[32]; + void *array[128]; size_t size; // get void*'s for all entries on the stack - size = backtrace(array, 32); + size = backtrace(array, 128); // print out all the frames to stderr fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, STDERR_FILENO); + + char** symbol_trace = backtrace_symbols(array, size); + + if (symbol_trace) + { + demangleAndPrintBacktrace(symbol_trace, size); + free(symbol_trace); + } + else + { + std::cerr << "Failed to read backtrace" << std::endl; + } if (GetConfig().crash_dump == CrashDump::Enabled) { diff --git a/src/Common/precompiled.h b/src/Common/precompiled.h index 2a92ea3e..bd956657 100644 --- a/src/Common/precompiled.h +++ b/src/Common/precompiled.h @@ -246,6 +246,12 @@ inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor, #error No definition for DLLEXPORT #endif +#if BOOST_OS_WINDOWS + #define NOEXPORT +#elif defined(__GNUC__) + #define NOEXPORT __attribute__ ((visibility ("hidden"))) +#endif + #ifdef __GNUC__ #include #endif