31 #define UNW_LOCAL_ONLY
32 #include <libunwind.h>
44#if defined(__GNUC__) && ! defined(__clang__)
45 #pragma GCC push_options
46 #pragma GCC optimize("-O0")
58 const size_t len = ::strlen(mangled_name);
59 if(
nullptr == mangled_name || 0 == len ) {
63 if( len > ctti_name_prefix->length()+2 &&
64 mangled_name == ::strstr(mangled_name, ctti_name_prefix->c_str()) )
66 std::string r( mangled_name + ctti_name_prefix->length() );
67 r.resize(r.length() - 1);
79 char* real_name = abi::__cxa_demangle(mangled_name,
nullptr,
nullptr, &status);
80 if (
nullptr == real_name ) {
81 return std::string(mangled_name);
84 if( 0 != status || 0 == ::strlen(real_name) ) {
85 res = std::string(mangled_name);
87 res = std::string(real_name);
109 if( 0 != ( res = unw_getcontext(&uc) ) ) {
113 if( 0 != ( res = unw_init_local(&cursor, &uc) ) ) {
117 bool last_frame_anon =
false;
118 while( unw_step(&cursor) > 0 && ( 0 > max_frames || ( max_frames + skip_frames ) > ( frame + 1 ) ) ) {
120 if( skip_frames > frame ) {
124 snprintf(cstr,
sizeof(cstr),
"%3zd: ", (ssize_t)frame);
125 std::string line(cstr);
127 if( 0 != ( res = unw_get_reg(&cursor, UNW_REG_IP, &ip) ) ) {
128 INFO_PRINT(
"unw_get_reg(IP): frame %zd, ERR %d\n", frame, res);
131 if( 0 != ( res = unw_get_reg(&cursor, UNW_REG_SP, &sp) ) ) {
132 INFO_PRINT(
"unw_get_reg(SP): frame %zd, ERR %d\n", frame, res);
135 if( 0 == unw_get_proc_name(&cursor, cstr,
sizeof(cstr), &offset) ) {
138 cstr[
sizeof(cstr) -1] = 0;
139 if ( (real_name = abi::__cxa_demangle(cstr,
nullptr,
nullptr, &status)) == nullptr ) {
142 line.append(real_name);
145 snprintf(cstr,
sizeof(cstr),
" + 0x%lx @ ip %p, sp %p", (
unsigned long)offset, (
void*)ip, (
void*)sp);
147 last_frame_anon =
false;
150 snprintf(cstr,
sizeof(cstr),
"__no_proc_name__ @ ip %p, sp %p", (
void*)ip, (
void*)sp);
151 append_line = !skip_anon_frames || !last_frame_anon;
152 last_frame_anon =
true;
161 (void)skip_anon_frames;
164 out.append(
"0: backtrace disabled\n");
169#if defined(__GNUC__) && ! defined(__clang__)
170 #pragma GCC pop_options
174 fprintf(stderr,
"%s",
get_backtrace(skip_anon_frames, max_frames, skip_frames).c_str());
179 fprintf(stderr,
"[%s] Debug: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str());
181 va_start (args, format);
182 vfprintf(stderr, format, args);
184 fprintf(stderr,
"\n");
189 fprintf(stderr,
"[%s] Wordy: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str());
191 va_start (args, format);
192 vfprintf(stderr, format, args);
194 fprintf(stderr,
"\n");
198void jau::ABORT_impl(
const char *func,
const char *file,
const int line,
const char * format, ...) noexcept {
199 fprintf(stderr,
"[%s] ABORT @ %s:%d %s: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str(), file, line, func);
201 va_start (args, format);
202 vfprintf(stderr, format, args);
204 fprintf(stderr,
"; last errno %d %s\n", errno, strerror(errno));
210void jau::ERR_PRINTv(
const char *func,
const char *file,
const int line,
const char * format, va_list args)
noexcept {
211 fprintf(stderr,
"[%s] Error @ %s:%d %s: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str(), file, line, func);
212 vfprintf(stderr, format, args);
213 fprintf(stderr,
"; last errno %d %s\n", errno, strerror(errno));
218void jau::ERR_PRINT_impl(
const char *prefix,
const bool backtrace,
const char *func,
const char *file,
const int line,
const char * format, ...) noexcept {
219 fprintf(stderr,
"[%s] %s @ %s:%d %s: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str(), prefix, file, line, func);
221 va_start (args, format);
222 vfprintf(stderr, format, args);
224 fprintf(stderr,
"; last errno %d %s\n", errno, strerror(errno));
231void jau::WARN_PRINTv(
const char *func,
const char *file,
const int line,
const char * format, va_list args)
noexcept {
232 fprintf(stderr,
"[%s] Warning @ %s:%d %s: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str(), file, line, func);
233 vfprintf(stderr, format, args);
234 fprintf(stderr,
"\n");
238void jau::WARN_PRINT_impl(
const char *func,
const char *file,
const int line,
const char * format, ...) noexcept {
239 fprintf(stderr,
"[%s] Warning @ %s:%d %s: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str(), file, line, func);
241 va_start (args, format);
242 vfprintf(stderr, format, args);
244 fprintf(stderr,
"\n");
249 fprintf(stderr,
"[%s] Info: ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str());
251 va_start (args, format);
252 vfprintf(stderr, format, args);
254 fprintf(stderr,
"\n");
260 fprintf(stderr,
"[%s] ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str());
263 va_start (args, format);
264 vfprintf(stderr, format, args);
266 fprintf(stderr,
"\n");
270int jau::fprintf_td(
const uint64_t elapsed_ms, FILE* stream,
const char * format, ...) noexcept {
271 int res = ::fprintf(stream,
"[%s] ",
jau::to_decstring(elapsed_ms,
',', 9).c_str());
273 va_start (args, format);
274 res += ::vfprintf(stream, format, args);
279 int res = ::fprintf(stream,
"[%s] ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str());
281 va_start (args, format);
282 res += ::vfprintf(stream, format, args);
288 fprintf(stderr,
"[%s] ",
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9).c_str());
290 va_start (args, format);
291 vfprintf(stderr, format, args);
293 fprintf(stderr,
"\n");
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[]
std::string demangle_name(const char *mangled_name) noexcept
Returns the demangled given mangled_name if successful, otherwise the mangled_name.
int_fast32_t snsize_t
Natural 'ssize_t' alternative using int_fast32_t as its natural sized type.
std::string to_decstring(const value_type &v, const char separator=',', const nsize_t width=0) noexcept
Produce a decimal string representation of an integral integer value.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
void ABORT_impl(const char *func, const char *file, const int line, const char *format,...) noexcept
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
void ERR_PRINTv(const char *func, const char *file, const int line, const char *format, va_list args) noexcept
Use for unconditional error messages, prefix '[elapsed_time] Error @ file:line func: '.
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 INFO_PRINT(const char *format,...) noexcept
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
void WARN_PRINTv(const char *func, const char *file, const int line, const char *format, va_list args) noexcept
Use for unconditional warning messages, prefix '[elapsed_time] Warning @ file:line func: '.
void DBG_PRINT_impl(const char *format,...) noexcept
void ERR_PRINT_impl(const char *prefix, const bool backtrace, const char *func, const char *file, const int line, const char *format,...) noexcept
void COND_PRINT_impl(const char *format,...) noexcept
void WORDY_PRINT_impl(const char *format,...) noexcept
void WARN_PRINT_impl(const char *func, const char *file, const int line, const char *format,...) noexcept
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,...