Fix: Support macOS (#6)

Simpler than I expected tbh. macOS uses the same backtrace and dladdr
functions, and with Clang for Xcode we can also just use cxxabi for
demangling.

Co-authored-by: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com>
This commit is contained in:
sean 2023-07-12 00:01:55 +02:00 committed by GitHub
parent a540803cd9
commit 6b55222a4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 21 deletions

View File

@ -28,11 +28,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
@ -172,7 +172,9 @@ if(
)
)
# Attempt to auto-config
if(UNIX)
if(APPLE)
set(CPPTRACE_GET_SYMBOLS_WITH_LIBDL ON)
elseif(UNIX)
if(HAS_BACKTRACE)
set(CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE On)
message(STATUS "Cpptrace auto config: Using libbacktrace for symbols")

View File

@ -5,10 +5,10 @@
🚧 WIP 🏗️
Cpptrace is a lightweight C++ stacktrace library supporting C++11 and greater on Linux, Unix, and Windows. The goal:
Cpptrace is a lightweight C++ stacktrace library supporting C++11 and greater on Linux, Unix, macOS and Windows. The goal:
Make stack traces simple for once.
Support for MacOS and cygwin/mingw will be added soon.
Support for cygwin/mingw will be added soon.
*Some day C++23's `<stacktrace>` will be ubiquitous, and maybe one day the msvc implementation will be acceptable*
@ -52,24 +52,24 @@ also manually set which back-end you want used.
**Unwinding**
| Library | CMake config | Windows | Linux | Info |
|---------|--------------|---------|-------|------|
| execinfo.h | `CPPTRACE_UNWIND_WITH_EXECINFO` | ❌ | ✔️ | Frames are captured with `execinfo.h`'s `backtrace`, part of libc. |
| winapi | `CPPTRACE_UNWIND_WITH_WINAPI` | ✔️ | ❌ | Frames are captured with `CaptureStackBackTrace`. |
| N/A | `CPPTRACE_UNWIND_WITH_NOTHING` | ✔️ | ✔️ | Unwinding is not done, stack traces will be empty. |
| Library | CMake config | Windows | Linux | macOS | Info |
|------------|---------------------------------|---------|-------|-------|--------------------------------------------------------------------|
| execinfo.h | `CPPTRACE_UNWIND_WITH_EXECINFO` | ❌ | ✔️ | ✔️ | Frames are captured with `execinfo.h`'s `backtrace`, part of libc. |
| winapi | `CPPTRACE_UNWIND_WITH_WINAPI` | ✔️ | ❌ | ❌ | Frames are captured with `CaptureStackBackTrace`. |
| N/A | `CPPTRACE_UNWIND_WITH_NOTHING` | ✔️ | ✔️ | ✔️ | Unwinding is not done, stack traces will be empty. |
These back-ends require a fixed buffer has to be created to read addresses into while unwinding. By default the buffer
can hold addresses for 100 frames (beyond the `skip` frames). This is configurable with `CPPTRACE_HARD_MAX_FRAMES`.
**Symbol resolution**
| Library | CMake config | Windows | Linux | Info |
|---------|--------------|---------|-------|------|
| 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), `CPPTRACE_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 needed for symbol information to be retrievable. |
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | ❌ | ✔️ | Symbols are resolved by invoking `addr2line` via `fork()`. |
| 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. |
| Library | CMake config | Windows | Linux | macOS | Info |
|--------------|------------------------------------------|---------|-------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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), `CPPTRACE_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 needed for symbol information to be retrievable. |
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | ❌ | ✔️ | ❌ | Symbols are resolved by invoking `addr2line` via `fork()`. |
| 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**

View File

@ -20,7 +20,28 @@ namespace cpptrace {
}
}
#else
#elif __APPLE__
#include <mach-o/dyld.h>
#include <sys/syslimits.h>
namespace cpptrace {
namespace detail {
inline const char* program_name() {
static std::string name;
if (!name.empty()) {
std::uint32_t bufferSize = PATH_MAX + 1;
char buffer[bufferSize];
if (_NSGetExecutablePath(buffer, &bufferSize) != 0)
return nullptr;
name.assign(buffer, bufferSize);
}
return name.c_str();
}
}
}
#elif __linux__
#include <linux/limits.h>
#include <unistd.h>