Added C++23 stacktrace backend
This commit is contained in:
parent
69581c9d58
commit
f56e8c5869
28
.github/workflows/build.yml
vendored
28
.github/workflows/build.yml
vendored
@ -106,6 +106,34 @@ jobs:
|
||||
-DLIBCPP_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
|
||||
${{matrix.config}}
|
||||
make
|
||||
# TODO: -DCMAKE_CXX_STANDARD isn't being honored?
|
||||
# build-linux-full-or-auto-23:
|
||||
# runs-on: ubuntu-22.04
|
||||
# strategy:
|
||||
# fail-fast: false
|
||||
# matrix:
|
||||
# compiler: [g++-12, clang++-14]
|
||||
# target: [Debug]
|
||||
# std: [23]
|
||||
# config: ["-DCPPTRACE_FULL_TRACE_WITH_STACKTRACE=On", ""]
|
||||
# exclude:
|
||||
# - config: "-DCPPTRACE_FULL_TRACE_WITH_STACKTRACE=On"
|
||||
# compiler: clang++-14
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: dependencies
|
||||
# run: sudo apt install gcc-12 g++-12 libgcc-12-dev
|
||||
# - name: build
|
||||
# run: |
|
||||
# mkdir -p build
|
||||
# cd build
|
||||
# cmake .. \
|
||||
# -DCMAKE_BUILD_TYPE=${{matrix.target}} \
|
||||
# -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
|
||||
# -DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||
# -DLIBCPP_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/include/backtrace.h \
|
||||
# ${{matrix.config}}
|
||||
# make
|
||||
build-windows-full-or-auto:
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
|
||||
@ -27,11 +27,11 @@ target_include_directories(
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpptrace/cpptrace>
|
||||
)
|
||||
|
||||
target_compile_features(
|
||||
cpptrace
|
||||
PUBLIC
|
||||
cxx_std_11
|
||||
)
|
||||
#target_compile_features(
|
||||
# cpptrace
|
||||
# PUBLIC
|
||||
# cxx_std_11
|
||||
#)
|
||||
|
||||
set_target_properties(
|
||||
cpptrace
|
||||
@ -48,6 +48,7 @@ target_compile_options(
|
||||
)
|
||||
|
||||
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_LIBDL "" OFF)
|
||||
@ -92,13 +93,23 @@ endfunction()
|
||||
check_support(HAS_EXECINFO has_execinfo.cpp "" "" "")
|
||||
check_support(HAS_BACKTRACE has_backtrace.cpp "" "backtrace" "${LIBCPP_BACKTRACE_PATH_DEFINITION}")
|
||||
check_support(HAS_CXXABI has_cxxabi.cpp "" "" "")
|
||||
if(NOT MSVC)
|
||||
set(STACKTRACE_LINK_LIB "stdc++_libbacktrace")
|
||||
else()
|
||||
set(STACKTRACE_LINK_LIB "")
|
||||
endif()
|
||||
check_support(HAS_STACKTRACE has_stacktrace.cpp "" "${STACKTRACE_LINK_LIB}" "")
|
||||
|
||||
# =============================================== Autoconfig full dump ===============================================
|
||||
# If nothing is specified, attempt to use libbacktrace's full dump
|
||||
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
|
||||
CPPTRACE_GET_SYMBOLS_WITH_DBGHELP OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_NOTHING OR
|
||||
CPPTRACE_UNWIND_WITH_EXECINFO OR
|
||||
CPPTRACE_UNWIND_WITH_WINAPI OR
|
||||
@ -106,7 +117,10 @@ if(
|
||||
)
|
||||
)
|
||||
# Attempt to auto-config
|
||||
if(HAS_BACKTRACE)
|
||||
if(HAS_STACKTRACE AND NOT WIN32)
|
||||
set(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE On)
|
||||
message(STATUS "Cpptrace auto config: Using C++23 <stacktrace> for the full trace")
|
||||
elseif(HAS_BACKTRACE)
|
||||
set(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE On)
|
||||
message(STATUS "Cpptrace auto config: Using libbacktrace for the full trace")
|
||||
endif()
|
||||
@ -117,6 +131,7 @@ endif()
|
||||
if(
|
||||
NOT (
|
||||
CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE OR
|
||||
CPPTRACE_FULL_TRACE_WITH_STACKTRACE OR
|
||||
CPPTRACE_UNWIND_WITH_EXECINFO OR
|
||||
CPPTRACE_UNWIND_WITH_WINAPI OR
|
||||
CPPTRACE_UNWIND_WITH_NOTHING
|
||||
@ -144,7 +159,11 @@ endif()
|
||||
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
|
||||
CPPTRACE_GET_SYMBOLS_WITH_DBGHELP OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_NOTHING
|
||||
)
|
||||
)
|
||||
@ -200,6 +219,14 @@ if(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 <stacktrace> 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()
|
||||
|
||||
12
README.md
12
README.md
@ -67,7 +67,7 @@ can hold addresses for 100 frames. This is configurable with `CPPTRACE_HARD_MAX_
|
||||
| libbacktrace | `CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE` | ❌ | ✔️ | Libbacktrace is already installed on most systems, or available through the compiler directly. If it is installed but backtrace.h is not already in the include path (this can happen when using clang when backtrace lives in gcc's include folder), `LIBCPP_BACKTRACE_PATH` can be used to specify where the library should be looked for. |
|
||||
| libdl | `CPPTRACE_GET_SYMBOLS_WITH_LIBDL` | ❌ | ✔️ | Libdl uses dynamic export information. Compiling with `-rdynamic` is often needed. |
|
||||
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | ❌ | ✔️ | Symbols are resolved by invoking `addr2line` via `fork()`. |
|
||||
| dbghelp.h | `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP` | ✔️ | ❌ | Dbghelp.h allows access to symbols via debug info. |
|
||||
| dbghelp | `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP` | ✔️ | ❌ | Dbghelp.h allows access to symbols via debug info. |
|
||||
| N/A | `CPPTRACE_GET_SYMBOLS_WITH_NOTHING` | ✔️ | ✔️ | No attempt is made to resolve symbols. |
|
||||
|
||||
**Demangling**
|
||||
@ -83,8 +83,14 @@ mangled.
|
||||
**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`. This is also the first configuration the auto config attempts to use. Full
|
||||
tracing with libbacktrace ignores `CPPTRACE_HARD_MAX_FRAMES`.
|
||||
`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`.
|
||||
|
||||
`<stacktrace>` 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_LIBBACKTRACE`. The cmake script will attempt to auto configure to this if
|
||||
possible. `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
|
||||
more back-ends can be added. Ideally this library can "just work" on systems, without additional installation work.
|
||||
|
||||
8
cmake/has_stacktrace.cpp
Normal file
8
cmake/has_stacktrace.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stacktrace>
|
||||
|
||||
int main() {
|
||||
std::stacktrace trace = std::stacktrace::current();
|
||||
for(const auto entry : trace) {
|
||||
(void)entry;
|
||||
}
|
||||
}
|
||||
30
src/full/full_trace_with_stacktrace.cpp
Normal file
30
src/full/full_trace_with_stacktrace.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifdef CPPTRACE_FULL_TRACE_WITH_STACKTRACE
|
||||
|
||||
#include <cpptrace/cpptrace.hpp>
|
||||
#include "libcpp_full_trace.hpp"
|
||||
#include "../platform/libcpp_common.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <stacktrace>
|
||||
|
||||
namespace cpptrace {
|
||||
namespace detail {
|
||||
CPPTRACE_FORCE_NO_INLINE
|
||||
std::vector<stacktrace_frame> generate_trace(size_t skip) {
|
||||
std::vector<stacktrace_frame> frames;
|
||||
std::stacktrace trace = std::stacktrace::current(skip + 1);
|
||||
for(const auto entry : trace) {
|
||||
frames.push_back({
|
||||
entry.native_handle(),
|
||||
entry.source_line(),
|
||||
-1,
|
||||
entry.source_file(),
|
||||
entry.description()
|
||||
});
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user