-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Library for getting stacktraces from arbitrary exceptions (#147)
- Loading branch information
Showing
10 changed files
with
637 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright Antony Polukhin, 2023-2024. | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See | ||
// accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#ifndef BOOST_STACKTRACE_THIS_THREAD_HPP | ||
#define BOOST_STACKTRACE_THIS_THREAD_HPP | ||
|
||
#include <boost/config.hpp> | ||
#ifdef BOOST_HAS_PRAGMA_ONCE | ||
# pragma once | ||
#endif | ||
|
||
#include <boost/stacktrace/stacktrace.hpp> | ||
|
||
namespace boost { namespace stacktrace { namespace this_thread { | ||
|
||
/// @brief Invoking the function with the enable parameter equal to `true` | ||
/// enables capturing of stacktraces by the current thread of execution at | ||
/// exception object construction if the `boost_stacktrace_from_exception` | ||
/// library is linked to the current binary; disables otherwise. | ||
/// | ||
/// Implements https://wg21.link/p2370r1 | ||
inline void set_capture_stacktraces_at_throw(bool enable = true) noexcept { | ||
#if defined(__GNUC__) && defined(__ELF__) | ||
if (impl::ref_capture_stacktraces_at_throw) { | ||
impl::ref_capture_stacktraces_at_throw() = enable; | ||
} | ||
#endif | ||
(void)enable; | ||
} | ||
|
||
/// @return whether the capturing of stacktraces by the current thread of | ||
/// execution is enabled and | ||
/// 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__) | ||
if (impl::ref_capture_stacktraces_at_throw) { | ||
return impl::ref_capture_stacktraces_at_throw(); | ||
} | ||
#endif | ||
return false; | ||
} | ||
|
||
}}} // namespace boost::stacktrace::this_thread | ||
|
||
#endif // BOOST_STACKTRACE_THIS_THREAD_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright Antony Polukhin, 2023-2024. | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See | ||
// accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#include <stddef.h> | ||
|
||
#if defined(__x86_64__) || defined(_M_X64) || defined(__MINGW32__) | ||
#define BOOST_STACKTRACE_ALWAYS_STORE_IN_PADDING 1 | ||
#else | ||
#define BOOST_STACKTRACE_ALWAYS_STORE_IN_PADDING 0 | ||
#endif | ||
|
||
|
||
extern "C" { | ||
|
||
// Developer note: helper to experiment with layouts of different | ||
// exception headers https://godbolt.org/z/rrcdPbh1P | ||
|
||
// https://github.com/llvm/llvm-project/blob/b3dd14ce07f2750ae1068fe62abbf2f3bd2cade8/libcxxabi/src/cxa_exception.h | ||
struct cxa_exception_begin_llvm { | ||
const char* reserve; | ||
size_t referenceCount; | ||
}; | ||
|
||
static cxa_exception_begin_llvm* exception_begin_llvm_ptr(void* ptr) { | ||
size_t kExceptionBeginOffset = ( | ||
sizeof(void*) == 8 ? 128 : 80 | ||
); | ||
return (cxa_exception_begin_llvm*)((char*)ptr - kExceptionBeginOffset); | ||
} | ||
|
||
// https://github.com/gcc-mirror/gcc/blob/5d2a360f0a541646abb11efdbabc33c6a04de7ee/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h#L100 | ||
struct cxa_exception_begin_gcc { | ||
size_t referenceCount; | ||
const char* reserve; | ||
}; | ||
|
||
static cxa_exception_begin_gcc* exception_begin_gcc_ptr(void* ptr) { | ||
size_t kExceptionBeginOffset = ( | ||
sizeof(void*) == 8 ? 128 : 96 | ||
); | ||
return (cxa_exception_begin_gcc*)((char*)ptr - kExceptionBeginOffset); | ||
} | ||
|
||
static void* get_current_exception_raw_ptr(void* exc_ptr) { | ||
// https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/libstdc%2B%2B-v3/libsupc%2B%2B/eh_ptr.cc#L147 | ||
return *static_cast<void**>(exc_ptr); | ||
} | ||
|
||
} // extern "C" | ||
|
||
|
Oops, something went wrong.