diff --git a/CMakeLists.txt b/CMakeLists.txt index 262a613..72b6e7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,9 +24,6 @@ endif() option(CPPTRACE_STATIC "" OFF) -option(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE "" OFF) -option(CPPTRACE_FULL_TRACE_WITH_STACKTRACE "" OFF) - option(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE "" OFF) option(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF "" OFF) option(CPPTRACE_GET_SYMBOLS_WITH_LIBDL "" OFF) @@ -119,11 +116,9 @@ if(MINGW OR NOT WIN32) # No need to bother checking in msvc, but do check in min endif() # =============================================== Autoconfig unwinding =============================================== -# Unwind back-ends (If not doing CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE) +# Unwind back-ends if( NOT ( - CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE OR - CPPTRACE_FULL_TRACE_WITH_STACKTRACE OR CPPTRACE_UNWIND_WITH_UNWIND OR CPPTRACE_UNWIND_WITH_EXECINFO OR CPPTRACE_UNWIND_WITH_WINAPI OR @@ -164,8 +159,6 @@ endif() # =============================================== Autoconfig symbols =============================================== if( NOT ( - CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE OR - CPPTRACE_FULL_TRACE_WITH_STACKTRACE OR CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE OR CPPTRACE_GET_SYMBOLS_WITH_LIBDL OR CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE OR @@ -217,8 +210,6 @@ set( src/cpptrace.cpp src/demangle/demangle_with_cxxabi.cpp src/demangle/demangle_with_nothing.cpp - src/full/full_trace_with_libbacktrace.cpp - src/full/full_trace_with_stacktrace.cpp src/symbols/symbols_with_addr2line.cpp src/symbols/symbols_with_dbghelp.cpp src/symbols/symbols_with_dl.cpp @@ -276,21 +267,6 @@ function(check_backtrace_error) endif() endfunction() -# Full -if(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE) - check_backtrace_error() - target_compile_definitions(cpptrace PUBLIC CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE) - target_link_libraries(cpptrace PRIVATE backtrace) -endif() - -if(CPPTRACE_FULL_TRACE_WITH_STACKTRACE) - if(NOT HAS_STACKTRACE) - message(WARNING "Cpptrace: CPPTRACE_FULL_TRACE_WITH_STACKTRACE specified but doesn't seem to be available.") - endif() - target_compile_definitions(cpptrace PUBLIC CPPTRACE_FULL_TRACE_WITH_STACKTRACE) - target_link_libraries(cpptrace PRIVATE "${STACKTRACE_LINK_LIB}") -endif() - # Symbols if(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE) check_backtrace_error() diff --git a/README.md b/README.md index 17c803e..132ada6 100644 --- a/README.md +++ b/README.md @@ -294,23 +294,13 @@ search the system path for `addr2line` at runtime. This is not the default to pr **Demangling** -Lastly, depending on other back-ends used a demangler back-end may be needed. A demangler back-end is not needed when -doing full traces with libbacktrace, getting symbols with addr2line, or getting symbols with dbghelp. +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. | -**Full tracing** - -Libbacktrace can generate a full stack trace itself, both unwinding and resolving symbols. This can be chosen with -`CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE`. The auto config attempts to use this if it is available. Full tracing with -libbacktrace ignores `CPPTRACE_HARD_MAX_FRAMES`. - -`` can of course also generate a full trace, if you're using >=C++23 and your compiler supports it. This is -controlled by `CPPTRACE_FULL_TRACE_WITH_STACKTRACE`. `CPPTRACE_HARD_MAX_FRAMES` is ignored. - **More?** There are plenty more libraries that can be used for unwinding, parsing debug information, and demangling. In the future @@ -321,8 +311,6 @@ more back-ends can be added. Ideally this library can "just work" on systems, wi Summary of all library configuration options: Back-ends: -- `CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On/Off` -- `CPPTRACE_FULL_TRACE_WITH_STACKTRACE=On/Off` - `CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF=On/Off` - `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP=On/Off` - `CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE=On/Off` diff --git a/ci/build-in-all-configs.py b/ci/build-in-all-configs.py index 493cbd8..92ae881 100644 --- a/ci/build-in-all-configs.py +++ b/ci/build-in-all-configs.py @@ -163,7 +163,7 @@ def main(): "compiler": ["g++-10", "clang++-14"], "target": ["Debug"], "std": ["11", "20"], - "config": ["-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""] + "config": [""] } exclude = [] run_matrix(matrix, exclude, build_full_or_auto) @@ -283,11 +283,7 @@ def main(): "std": ["11", "20"], "config": [""] } - exclude = [ - { - "config": "-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On" - } - ] + exclude = [] run_matrix(matrix, exclude, build_full_or_auto) global failed diff --git a/ci/test-all-configs.py b/ci/test-all-configs.py index b0b6413..65da12f 100644 --- a/ci/test-all-configs.py +++ b/ci/test-all-configs.py @@ -81,10 +81,6 @@ def output_matches(output: str, params: Tuple[str]): max_line_diff = MAX_LINE_DIFF if "CPPTRACE_UNWIND_WITH_UNWIND" in params: max_line_diff = 0 - if "CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE" in params: - max_line_diff = 0 - if "CPPTRACE_FULL_TRACE_WITH_STACKTRACE" in params: - max_line_diff = 0 errored = False @@ -321,7 +317,7 @@ def main(): "compiler": ["g++-10", "clang++-14"], "target": ["Debug"], "std": ["11", "20"], - "config": ["-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On", ""] + "config": [""] } exclude = [] run_matrix(matrix, exclude, build_and_test_full_or_auto) @@ -441,11 +437,7 @@ def main(): "std": ["11", "20"], "config": [""] } - exclude = [ - { - "config": "-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On" - } - ] + exclude = [] run_matrix(matrix, exclude, build_and_test_full_or_auto) global failed diff --git a/cmake/has_backtrace.cpp b/cmake/has_backtrace.cpp deleted file mode 100644 index 784994a..0000000 --- a/cmake/has_backtrace.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef CPPTRACE_BACKTRACE_PATH -#include CPPTRACE_BACKTRACE_PATH -#else -#include -#endif - -int main() { - backtrace_state* state = backtrace_create_state(nullptr, true, nullptr, nullptr); -} diff --git a/lint.sh b/lint.sh index 4cae5d0..1098283 100644 --- a/lint.sh +++ b/lint.sh @@ -4,7 +4,7 @@ status=0 while read f do echo checking $f - flags="-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE -DCPPTRACE_FULL_TRACE_WITH_STACKTRACE -DCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE -DCPPTRACE_GET_SYMBOLS_WITH_LIBDL -DCPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE -DCPPTRACE_GET_SYMBOLS_WITH_NOTHING -DCPPTRACE_UNWIND_WITH_EXECINFO -DCPPTRACE_UNWIND_WITH_UNWIND -DCPPTRACE_UNWIND_WITH_NOTHING -DCPPTRACE_DEMANGLE_WITH_CXXABI -DCPPTRACE_DEMANGLE_WITH_NOTHING -DCPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH" + flags="-DCPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE -DCPPTRACE_GET_SYMBOLS_WITH_LIBDL -DCPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE -DCPPTRACE_GET_SYMBOLS_WITH_NOTHING -DCPPTRACE_UNWIND_WITH_EXECINFO -DCPPTRACE_UNWIND_WITH_UNWIND -DCPPTRACE_UNWIND_WITH_NOTHING -DCPPTRACE_DEMANGLE_WITH_CXXABI -DCPPTRACE_DEMANGLE_WITH_NOTHING -DCPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH" clang-tidy $f -- -std=c++11 -Iinclude $@ $flags ret=$? if [ $ret -ne 0 ]; then diff --git a/src/cpptrace.cpp b/src/cpptrace.cpp index 657b494..b1fb9ce 100644 --- a/src/cpptrace.cpp +++ b/src/cpptrace.cpp @@ -7,46 +7,12 @@ #include #include -#if !(defined(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE) || defined(CPPTRACE_FULL_TRACE_WITH_STACKTRACE)) - #include "symbols/symbols.hpp" #include "unwind/unwind.hpp" #include "demangle/demangle.hpp" #include "platform/common.hpp" #include "platform/utils.hpp" -namespace cpptrace { - CPPTRACE_FORCE_NO_INLINE CPPTRACE_API - std::vector generate_trace(std::uint32_t skip) { - std::vector frames = detail::capture_frames(skip + 1); - std::vector trace = detail::resolve_frames(frames); - for(auto& frame : trace) { - frame.symbol = detail::demangle(frame.symbol); - } - return trace; - } -} - -#else - -// full trace - -#include "full/full_trace.hpp" -#include "demangle/demangle.hpp" - -namespace cpptrace { - CPPTRACE_FORCE_NO_INLINE CPPTRACE_API - std::vector generate_trace(std::uint32_t skip) { - auto trace = detail::generate_trace(skip + 1); - for(auto& entry : trace) { - entry.symbol = detail::demangle(entry.symbol); - } - return trace; - } -} - -#endif - #define ESC "\033[" #define RESET ESC "0m" #define RED ESC "31m" @@ -57,6 +23,16 @@ namespace cpptrace { #define CYAN ESC "36m" namespace cpptrace { + CPPTRACE_FORCE_NO_INLINE CPPTRACE_API + std::vector generate_trace(std::uint32_t skip) { + std::vector frames = detail::capture_frames(skip + 1); + std::vector trace = detail::resolve_frames(frames); + for(auto& frame : trace) { + frame.symbol = detail::demangle(frame.symbol); + } + return trace; + } + CPPTRACE_API void print_trace(std::uint32_t skip) { detail::enable_virtual_terminal_processing_if_needed(); diff --git a/src/full/full_trace.hpp b/src/full/full_trace.hpp deleted file mode 100644 index bc027d4..0000000 --- a/src/full/full_trace.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FULL_TRACE_HPP -#define FULL_TRACE_HPP - -#include -#include "../platform/common.hpp" -#include "../platform/utils.hpp" - -#include -#include - -namespace cpptrace { -namespace detail { - CPPTRACE_FORCE_NO_INLINE - std::vector generate_trace(size_t skip); -} -} - -#endif diff --git a/src/full/full_trace_with_libbacktrace.cpp b/src/full/full_trace_with_libbacktrace.cpp deleted file mode 100644 index babe8e2..0000000 --- a/src/full/full_trace_with_libbacktrace.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#ifdef CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE - -#include -#include "../platform/program_name.hpp" -#include "../platform/common.hpp" -#include "../platform/utils.hpp" - -#include -#include -#include -#include - -#ifdef CPPTRACE_BACKTRACE_PATH -#include CPPTRACE_BACKTRACE_PATH -#else -#include -#endif - -namespace cpptrace { -namespace detail { - struct trace_data { - // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) - std::vector& frames; - // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) - size_t& skip; - }; - - int full_callback(void* data_pointer, uintptr_t address, const char* file, int line, const char* symbol) { - trace_data& data = *reinterpret_cast(data_pointer); - if(data.skip > 0) { - data.skip--; - } else if(address == uintptr_t(-1)) { - // sentinel for libbacktrace, stop tracing - return 1; - } else { - data.frames.push_back({ - address, - static_cast(line), - 0, - file ? file : "", - symbol ? symbol : "" - }); - } - return 0; - } - - void syminfo_callback(void* data, uintptr_t, const char* symbol, uintptr_t, uintptr_t) { - stacktrace_frame& frame = *static_cast(data); - frame.symbol = symbol ? symbol : ""; - } - - void error_callback(void*, const char* msg, int errnum) { - nonfatal_error(stringf("libbacktrace error: %s, code %d", msg, errnum)); - } - - backtrace_state* get_backtrace_state() { - static std::mutex mutex; - const std::lock_guard lock(mutex); - // backtrace_create_state must be called only one time per program - // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) - static backtrace_state* state = nullptr; - static bool called = false; - if(!called) { - state = backtrace_create_state(nullptr, true, error_callback, nullptr); - called = true; - } - return state; - } - - CPPTRACE_FORCE_NO_INLINE - std::vector generate_trace(size_t skip) { - std::vector frames; - skip++; // add one for this call - trace_data data { frames, skip }; - backtrace_full(get_backtrace_state(), 0, full_callback, error_callback, &data); - for(auto& frame : frames) { - if(frame.symbol.empty()) { - // fallback, try to at least recover the symbol name with backtrace_syminfo - backtrace_syminfo( - get_backtrace_state(), - frame.address, - syminfo_callback, - error_callback, - &frame - ); - } - } - return frames; - } -} -} - -#endif diff --git a/src/full/full_trace_with_stacktrace.cpp b/src/full/full_trace_with_stacktrace.cpp deleted file mode 100644 index b9f6a22..0000000 --- a/src/full/full_trace_with_stacktrace.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifdef CPPTRACE_FULL_TRACE_WITH_STACKTRACE - -#include -#include "full_trace.hpp" -#include "../platform/common.hpp" -#include "../platform/utils.hpp" - -#include -#include - -namespace cpptrace { -namespace detail { - CPPTRACE_FORCE_NO_INLINE - std::vector generate_trace(size_t skip) { - std::vector frames; - std::stacktrace trace = std::stacktrace::current(skip + 1); - for(const auto entry : trace) { - frames.push_back({ - entry.native_handle(), - entry.source_line(), - 0, - entry.source_file(), - entry.description() - }); - } - return frames; - } -} -} - -#endif