21 #ifndef Rcpp__exceptions_impl__h
22 #define Rcpp__exceptions_impl__h
25 #ifndef RCPP_DEMANGLER_ENABLED
26 # if defined(_WIN32) || \
27 defined(__FreeBSD__) || \
28 defined(__NetBSD__) || \
29 defined(__OpenBSD__) || \
30 defined(__CYGWIN__) || \
33 defined(__MUSL__) || \
34 defined(__HAIKU__) || \
36 # define RCPP_DEMANGLER_ENABLED 0
37 # elif defined(__GNUC__) || defined(__clang__)
38 # include <execinfo.h>
39 # define RCPP_DEMANGLER_ENABLED 1
41 # define RCPP_DEMANGLER_ENABLED 0
48 #if RCPP_DEMANGLER_ENABLED
49 static inline std::string demangler_one(
const char* input) {
51 static std::string buffer;
54 size_t last_open = buffer.find_last_of(
'(');
55 size_t last_close = buffer.find_last_of(
')');
56 if (last_open == std::string::npos ||
57 last_close == std::string::npos) {
60 std::string function_name = buffer.substr(last_open + 1, last_close - last_open - 1);
62 size_t function_plus = function_name.find_last_of(
'+');
63 if (function_plus != std::string::npos) {
64 function_name.resize(function_plus);
66 buffer.replace(last_open + 1, function_name.size(),
demangle(function_name));
76 #if RCPP_DEMANGLER_ENABLED
78 const size_t max_depth = 100;
80 void *stack_addrs[max_depth];
82 stack_depth = backtrace(stack_addrs, max_depth);
83 char **stack_strings = backtrace_symbols(stack_addrs, stack_depth);
85 std::transform(stack_strings + 1, stack_strings + stack_depth,
86 std::back_inserter(
stack), demangler_one);
104 trace.
attr(
"class") =
"Rcpp_stack_trace";
AttributeProxy attr(const std::string &name)
std::vector< std::string > stack
void copy_stack_trace_to_r() const
void record_stack_trace()
std::string demangle(const std::string &name)
static internal::NamedPlaceHolder _
attribute_hidden SEXP rcpp_set_stack_trace(SEXP e)