33 #define UNW_LOCAL_ONLY
34 #include <libunwind.h>
46#if defined(__GNUC__) && ! defined(__clang__)
47 #pragma GCC push_options
48 #pragma GCC optimize("-O0")
60 const size_t len = ::strlen(mangled_name);
61 if(
nullptr == mangled_name || 0 == len ) {
65 if( len > ctti_name_prefix->length()+2 &&
66 mangled_name == ::strstr(mangled_name, ctti_name_prefix->c_str()) )
68 std::string r( mangled_name + ctti_name_prefix->length() );
69 r.resize(r.length() - 1);
81 char* real_name = abi::__cxa_demangle(mangled_name,
nullptr,
nullptr, &status);
82 if (
nullptr == real_name ) {
83 return std::string(mangled_name);
86 if( 0 != status || 0 == ::strlen(real_name) ) {
87 res = std::string(mangled_name);
89 res = std::string(real_name);
112 if( 0 != ( res = unw_getcontext(&uc) ) ) {
116 if( 0 != ( res = unw_init_local(&cursor, &uc) ) ) {
120 bool last_frame_anon =
false;
121 while( unw_step(&cursor) > 0 && ( 0 > max_frames || ( max_frames + skip_frames ) > ( frame + 1 ) ) ) {
123 if( skip_frames > frame ) {
127 snprintf(cstr,
sizeof(cstr),
"%3zd: ", (ssize_t)frame);
128 std::string line(cstr);
130 if( 0 != ( res = unw_get_reg(&cursor, UNW_REG_IP, &ip) ) ) {
131 jau_INFO_PRINT(
"unw_get_reg(IP): frame %zd, ERR %d\n", frame, res);
134 if( 0 != ( res = unw_get_reg(&cursor, UNW_REG_SP, &sp) ) ) {
135 jau_INFO_PRINT(
"unw_get_reg(SP): frame %zd, ERR %d\n", frame, res);
138 if( 0 == unw_get_proc_name(&cursor, cstr,
sizeof(cstr), &offset) ) {
141 cstr[
sizeof(cstr) -1] = 0;
142 if ( (real_name = abi::__cxa_demangle(cstr,
nullptr,
nullptr, &status)) ==
nullptr ) {
145 line.append(real_name);
148 snprintf(cstr,
sizeof(cstr),
" + 0x%lx @ ip %p, sp %p", (
unsigned long)offset, (
void*)ip, (
void*)sp);
150 last_frame_anon =
false;
153 snprintf(cstr,
sizeof(cstr),
"__no_proc_name__ @ ip %p, sp %p", (
void*)ip, (
void*)sp);
154 append_line = !skip_anon_frames || !last_frame_anon;
155 last_frame_anon =
true;
164 (void)skip_anon_frames;
167 out.append(
"0: backtrace disabled\n");
173#if defined(__GNUC__) && ! defined(__clang__)
174 #pragma GCC pop_options
178 ::fprintf(stderr,
"%s",
get_backtrace(skip_anon_frames, max_frames, skip_frames).c_str());
static const std::string ctti_name_prefix_clang1
int jaulib_id_entryfunc()
static const std::string ctti_name_prefix_gcc1
On aarch64 using g++ (Debian 10.2.1-6) 10.2.1 20210110 optimization of jau::get_backtrace(....
static const std::string * ctti_name_prefixes[]
#define jau_INFO_PRINT(fmt,...)
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
std::string demangle_name(const char *mangled_name) noexcept
Returns the demangled given mangled_name if successful, otherwise the mangled_name.
sint_bytes_t< sizeof(long int)> snsize_t
Natural 'ssize_t' alternative using int<XX>_t with xx = sizeof(long int)*8 as its natural sized type,...
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
std::string get_backtrace(const bool skip_anon_frames, const jau::snsize_t max_frames=-1, const jau::snsize_t skip_frames=1) noexcept
Returns a de-mangled backtrace string separated by newline excluding this function.
void print_backtrace(const bool skip_anon_frames, const jau::snsize_t max_frames=-1, const jau::snsize_t skip_frames=2) noexcept
Prints the de-mangled backtrace string separated by newline excluding this function to stderr,...