diff --git a/CMakeLists.txt b/CMakeLists.txt index 47a6a61..7eb09a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ option(CPPTRACE_UNWIND_WITH_WINAPI "" OFF) option(CPPTRACE_UNWIND_WITH_NOTHING "" OFF) option(CPPTRACE_DEMANGLE_WITH_CXXABI "" OFF) +option(CPPTRACE_DEMANGLE_WITH_WINAPI "" OFF) option(CPPTRACE_DEMANGLE_WITH_NOTHING "" OFF) set(CPPTRACE_BACKTRACE_PATH "" CACHE STRING "Path to backtrace.h, if the compiler doesn't already know it. Check /usr/lib/gcc/x86_64-linux-gnu/*/include.") @@ -187,12 +188,16 @@ endif() if( NOT ( CPPTRACE_DEMANGLE_WITH_CXXABI OR + CPPTRACE_DEMANGLE_WITH_WINAPI OR CPPTRACE_DEMANGLE_WITH_NOTHING ) ) if(HAS_CXXABI) - message(STATUS "Cpptrace auto config: Using cxxabi for symbols") + message(STATUS "Cpptrace auto config: Using cxxabi for demangling") set(CPPTRACE_DEMANGLE_WITH_CXXABI On) + elseif(WIN32 AND NOT MINGW) + message(STATUS "Cpptrace auto config: Using dbghelp for demangling") + set(CPPTRACE_DEMANGLE_WITH_WINAPI On) else() set(CPPTRACE_DEMANGLE_WITH_NOTHING On) endif() @@ -210,6 +215,7 @@ set( sources src/cpptrace.cpp src/demangle/demangle_with_cxxabi.cpp + src/demangle/demangle_with_winapi.cpp src/demangle/demangle_with_nothing.cpp src/symbols/symbols_with_addr2line.cpp src/symbols/symbols_with_dbghelp.cpp @@ -361,6 +367,11 @@ if(CPPTRACE_DEMANGLE_WITH_CXXABI) target_compile_definitions(cpptrace PUBLIC CPPTRACE_DEMANGLE_WITH_CXXABI) endif() +if(CPPTRACE_DEMANGLE_WITH_WINAPI) + target_compile_definitions(cpptrace PUBLIC CPPTRACE_DEMANGLE_WITH_WINAPI) + target_link_libraries(cpptrace PRIVATE dbghelp) +endif() + if(CPPTRACE_DEMANGLE_WITH_NOTHING) target_compile_definitions(cpptrace PUBLIC CPPTRACE_DEMANGLE_WITH_NOTHING) endif() diff --git a/README.md b/README.md index caae618..1d20f3b 100644 --- a/README.md +++ b/README.md @@ -416,10 +416,11 @@ search the system path for `addr2line` at runtime. This is not the default to pr Lastly, depending on other back-ends used a demangler back-end may be needed. -| Library | CMake config | Platforms | Info | -| -------- | -------------------------------- | ------------------- | ---------------------------------------------------------------------------------- | -| cxxabi.h | `CPPTRACE_DEMANGLE_WITH_CXXABI` | Linux, macos, mingw | Should be available everywhere other than [msvc](https://godbolt.org/z/93ca9rcdz). | -| N/A | `CPPTRACE_DEMANGLE_WITH_NOTHING` | all | Don't attempt to do anything beyond what the symbol resolution back-end does. | +| Library | CMake config | Platforms | Info | +| --------- | -------------------------------- | ------------------- | ---------------------------------------------------------------------------------- | +| cxxabi.h | `CPPTRACE_DEMANGLE_WITH_CXXABI` | Linux, macos, mingw | Should be available everywhere other than [msvc](https://godbolt.org/z/93ca9rcdz). | +| dbghelp.h | `CPPTRACE_DEMANGLE_WITH_WINAPI` | Windows | Demangle with `UnDecorateSymbolName`. | +| N/A | `CPPTRACE_DEMANGLE_WITH_NOTHING` | all | Don't attempt to do anything beyond what the symbol resolution back-end does. | **More?** @@ -442,6 +443,7 @@ Back-ends: - `CPPTRACE_UNWIND_WITH_WINAPI=On/Off` - `CPPTRACE_UNWIND_WITH_NOTHING=On/Off` - `CPPTRACE_DEMANGLE_WITH_CXXABI=On/Off` +- `CPPTRACE_DEMANGLE_WITH_WINAPI=On/Off` - `CPPTRACE_DEMANGLE_WITH_NOTHING=On/Off` Back-end configuration: diff --git a/src/demangle/demangle_with_winapi.cpp b/src/demangle/demangle_with_winapi.cpp new file mode 100644 index 0000000..be9236a --- /dev/null +++ b/src/demangle/demangle_with_winapi.cpp @@ -0,0 +1,26 @@ +#ifdef CPPTRACE_DEMANGLE_WITH_WINAPI + +#include "demangle.hpp" + +#include +#include + +#include +#include + +namespace cpptrace { +namespace detail { + std::string demangle(const std::string& name) { + char buffer[500]; + auto ret = UnDecorateSymbolName(name.c_str(), buffer, sizeof(buffer) - 1, 0); + if(ret == 0) { + return name; + } else { + buffer[ret] = 0; // just in case, ms' docs unclear if null terminator inserted + return buffer; + } + } +} +} + +#endif