Skip to content

Commit

Permalink
docs and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin committed Feb 4, 2024
1 parent 034ecc4 commit 78ba546
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 1 deletion.
58 changes: 58 additions & 0 deletions doc/stacktrace.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,64 @@ Generic recommendation is to *avoid signal handlers! Use* platform specific ways
]


[endsect]

[section Stacktrace from arbitrary exception]

[warning At the moment the functionality is only available for some of the
popular cxx run-times for POSIX systems. Make sure that your platform
is supported by running some tests.
]

The library provides a way to get stacktrace from an exception as if the
stacktrace was captured at the point the exception was thrown. Works even if
the exception was thrown from a third party binary library.

Link with
`boost_stacktrace_from_exception` library (or just `LD_PRELOAD` it!) and call
boost::stacktrace::stacktrace::from_current_exception() to get the trace:

```
#include <iostream>
#include <stdexcept>
#include <string_view>
#include <boost/stacktrace.hpp>

void foo(std::string_view key);
void bar(std::string_view key);

int main() {
try {
foo("test1");
bar("test2");
} catch (const std::exception& exc) {
boost::stacktrace::stacktrace trace = std::stacktrace::from_current_exception(); // <---
std::cerr << "Caught exception: " << exc.what() << ", trace:\n" << trace;
}
}
```

The output of the above sample may be the following:

```
Caught exception: std::map::at, trace:
0# get_data_from_config(std::string_view) at /home/axolm/basic.cpp:600
1# bar(std::string_view) at /home/axolm/basic.cpp:6
2# main at /home/axolm/basic.cpp:17
```

With the above technique a developer can locate the source file and the function
that has thrown the exception without a debugger help. it is especially useful
for testing in containers (github CI, other CIs), where the developer has no
direct access to the testing environment and reproducing the issue is
complicated.

Note that linking with `boost_stacktrace_from_exception` may increase memory
consumption of the application, as the exceptions now additionally store traces.

At runtime switch boost::stacktrace::this_thread::set_capture_stacktraces_at_throw()
allows to disable/enable capturing and storing traces in exceptions.

[endsect]


Expand Down
3 changes: 3 additions & 0 deletions include/boost/stacktrace/this_thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ inline void set_capture_stacktraces_at_throw(bool enable = true) noexcept {
/// boost::stacktrace::basic_stacktrace::from_current_exception may return a
/// non empty stacktrace.
///
/// Returns true if set_capture_stacktraces_at_throw(false) was not called
/// and the `boost_stacktrace_from_exception` is linked to the current binary.
///
/// Implements https://wg21.link/p2370r1
inline bool get_capture_stacktraces_at_throw() noexcept {
#if defined(__GNUC__) && defined(__ELF__)
Expand Down
5 changes: 5 additions & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ test-suite stacktrace_tests
[ run test_from_exception_none.cpp : : : $(LINKSHARED_BT) <debug-symbols>on : from_exception_none_bt ]
[ run test_from_exception_none.cpp : : : <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) <debug-symbols>on : from_exception_none_bt_ho ]

[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BASIC) <debug-symbols>on : from_exception_disabled_basic ]
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) <debug-symbols>on : from_exception_disabled_basic_ho ]
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BT) <debug-symbols>on : from_exception_disabled_bt ]
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) : from_exception_disabled_bt_ho ]

[ link test_from_exception.cpp : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BASIC) <debug-symbols>on : from_exception_basic ]
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BT) <debug-symbols>on : from_exception_bt ]

Expand Down
2 changes: 2 additions & 0 deletions test/test_from_exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_from_other_thread() {
int main() {
const test_no_pending_on_finish guard{};

BOOST_TEST(boost::stacktrace::this_thread::get_capture_stacktraces_at_throw());

test_no_exception();
test_trace_from_exception();
test_after_other_exception();
Expand Down
4 changes: 3 additions & 1 deletion test/test_from_exception_none.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_no_trace_from_exception() {
}

int main() {
test_no_trace_from_exception();
boost::stacktrace::this_thread::set_capture_stacktraces_at_throw(false);
BOOST_TEST(!boost::stacktrace::this_thread::get_capture_stacktraces_at_throw());
test_no_trace_from_exception();

return boost::report_errors();
}

0 comments on commit 78ba546

Please sign in to comment.