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);
111 if( 0 != ( res = unw_getcontext(&uc) ) ) {
115 if( 0 != ( res = unw_init_local(&cursor, &uc) ) ) {
119 bool last_frame_anon =
false;
120 while( unw_step(&cursor) > 0 && ( 0 > max_frames || ( max_frames + skip_frames ) > ( frame + 1 ) ) ) {
122 if( skip_frames > frame ) {
126 snprintf(cstr,
sizeof(cstr),
"%3zd: ", (ssize_t)frame);
127 std::string line(cstr);
129 if( 0 != ( res = unw_get_reg(&cursor, UNW_REG_IP, &ip) ) ) {
130 INFO_PRINT(
"unw_get_reg(IP): frame %zd, ERR %d\n", frame, res);
133 if( 0 != ( res = unw_get_reg(&cursor, UNW_REG_SP, &sp) ) ) {
134 INFO_PRINT(
"unw_get_reg(SP): frame %zd, ERR %d\n", frame, res);
137 if( 0 == unw_get_proc_name(&cursor, cstr,
sizeof(cstr), &offset) ) {
140 cstr[
sizeof(cstr) -1] = 0;
141 if ( (real_name = abi::__cxa_demangle(cstr,
nullptr,
nullptr, &status)) ==
nullptr ) {
144 line.append(real_name);
147 snprintf(cstr,
sizeof(cstr),
" + 0x%lx @ ip %p, sp %p", (
unsigned long)offset, (
void*)ip, (
void*)sp);
149 last_frame_anon =
false;
152 snprintf(cstr,
sizeof(cstr),
"__no_proc_name__ @ ip %p, sp %p", (
void*)ip, (
void*)sp);
153 append_line = !skip_anon_frames || !last_frame_anon;
154 last_frame_anon =
true;
163 (void)skip_anon_frames;
166 out.append(
"0: backtrace disabled\n");
171#if defined(__GNUC__) && ! defined(__clang__)
172 #pragma GCC pop_options
176 ::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 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,...