Simple, portable, and self-contained stacktrace library for C++11 and newer
Simple, portable, and self-contained stacktrace library for C++11 and newer
In addition to providing access to stack traces, cpptrace also provides a mechanism for getting stacktraces from thrown exceptions which is immensely valuable for debugging and triaging. More info below.
Cpptrace also has a C API, docs here.
namespace cpptraceCPPTRACE_TRY and CPPTRACE_CATCH)
cpptrace::try_catchGenerating stack traces is as easy as:
#include <cpptrace/cpptrace.hpp>
void trace() {
cpptrace::generate_trace().print();
}Cpptrace can also retrieve function inlining information on optimized release builds:
Cpptrace provides access to resolved stack traces as well as fast and lightweight raw traces (just addresses) that can be resolved later:
const auto raw_trace = cpptrace::generate_raw_trace();
// then later
raw_trace.resolve().print();One of the most important features cpptrace offers is the ability to retrieve stack traces on arbitrary exceptions. More information on this system below.
#include <cpptrace/from_current.hpp>
#include <iostream>
#include <stdexcept>
void foo() {
throw std::runtime_error("foo failed");
}
int main() {
CPPTRACE_TRY {
foo();
} CPPTRACE_CATCH(const std::exception& e) {
std::cerr<<"Exception: "<<e.what()<<std::endl;
cpptrace::from_current_exception().print();
}
}Cpptrace also provides a handful of traced exception objects that store stack traces when thrown. This is useful when
the exceptions might not be caught by CPPTRACE_CATCH:
#include <cpptrace/cpptrace.hpp>
void trace() {
throw cpptrace::logic_error("This wasn't supposed to happen!");
}Additional notable features:
std::exceptions and wrapping them in traced exceptionsinclude(FetchContent)
FetchContent_Declare(
cpptrace
GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git
GIT_TAG v1.0.4 # <HASH or TAG>
)
FetchContent_MakeAvailable(cpptrace)
target_link_libraries(your_target cpptrace::cpptrace)
# Needed for shared library builds on windows: copy cpptrace.dll to the same directory as the
# executable for your_target
if(WIN32)
add_custom_command(
TARGET your_target POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:cpptrace::cpptrace>
$<TARGET_FILE_DIR:your_target>
)
endif()Be sure to configure with -DCMAKE_BUILD_TYPE=Debug or -DCMAKE_BUILD_TYPE=RelWithDebInfo for symbols and line
information.
On macOS it is recommended to generate a .dSYM file, see Platform Logistics below.
For other ways to use the library, such as through package managers, a system-wide installation, or on a platform without internet access see How to Include The Library below.
[!IMPORTANT] Debug info (
-g//Z7//Zi//DEBUG/-DBUILD_TYPE=Debug/-DBUILD_TYPE=RelWithDebInfo) is required for complete trace information.
cpptrace::generate_trace() can be used to generate a stacktrace object at the current call site. Resolved frames can
be accessed from this object with .frames and the trace can be printed with .print(). Cpptrace also provides a
method to get light-weight raw traces with cpptrace::generate_raw_trace(), which are just vectors of program counters,
which can be resolved at a later time.
namespace cpptraceAll functions are thread-safe unless otherwise noted.
The core resolved stack trace object. Generate a trace with cpptrace::generate_trace() or
cpptrace::stacktrace::current(). On top of a set of helper functions struct stacktrace allows
direct access to frames as well as iterators.
cpptrace::stacktrace::print can be used to print a stacktrace. cpptrace::stacktrace::print_with_snippets can be used
to print a stack trace with source code snippets.
…Object traces contain the most basic information needed to construct a stack trace outside the currently running executable. It contains the raw address, the address in the binary (ASLR and the object file's memory space and whatnot is resolved), and the path to the object the instruction pointer is located in.
…Raw trace access: A vector of program counters. These are ideal for fast and cheap traces you want to resolve later.
Note it is important executables and shared libraries in memory aren't somehow unmapped otherwise libdl calls (and
GetModuleFileName in windows) will fail to figure out where the program counter corresponds to.
namespace cpptrace {
struct raw_trace {
std::vector<frame_ptr> frames;
static raw_trace current(std::size_t skip = 0);
static raw_trace current(std::size_t skip, std::size_t max_depth);
object_trace resolve_object_trace() const;
stacktrace resolve() const;
void clear();
bool empty() const noexcept;
/* iterators exist for this object */
};
raw_trace generate_raw_trace(std::size_t skip = 0);
raw_trace generate_raw_trace(std::size_t skip, std::size_t max_depth);
}cpptrace::demangle is a helper function for name demangling, since it has to implement that helper internally anyways.
cpptrace::basename is a helper for custom formatters that extracts a base file name from a path.
cpptrace::prettify_symbol is a helper for custom formatters that applies a number of transformations to clean up long
symbol names. For example, it turns std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
into std::string.
cpptrace::prune_symbol is a helper for custom formatters that prunes demangled symbols by removing return types,
template arguments, and function parameters. It also does some minimal normalization. For example, it prunes
ns::S<int, float>::~S() to ns::S::~S. If cpptrace is unable to parse the symbol it will return the original symbol.
cpptrace::get_snippet gets a text snippet, if possible, from for the given source file for +/- context_size lines
around line.
cpptrace::isatty and the fileno definitions are useful for deciding whether to use color when printing stack traces.
cpptrace::register_terminate_handler() is a helper function to set a custom std::terminate handler that prints a
stack trace from a cpptrace exception (more info below) and otherwise behaves like the normal terminate handler.
…Cpptrace provides a configurable formatter for stack trace printing which supports some common options. Formatters are configured with a sort of builder pattern, e.g.:
auto formatter = cpptrace::formatter{}
.header("Stack trace:")
.addresses(cpptrace::formatter::address_mode::object)
.snippets(true);This API is available through the <cpptrace/formatting.hpp> header.
Synopsis:
…Options:
| Setting | Description | Default |
|---|---|---|
header |
Header line printed before the trace | Stack trace (most recent call first): |
colors |
Default color mode for the trace | automatic, which attempts to detect if the target stream is a terminal |
addresses |
Raw addresses, object addresses, or no addresses | raw |
paths |
Full paths or just filenames | full |
snippets |
Whether to include source code snippets | false |
snippet_context |
How many lines of source context to show in a snippet | 2 |
columns |
Whether to include column numbers if present | true |
No open issues yet, or sync has not completed.