3 #ifdef HAVE_SYS_CDEFS_H
4 # include <sys/cdefs.h>
5 #elif defined(HAVE_SYS_FEATURE_TESTS_H)
6 # include <sys/feature_tests.h>
8 # include <sys/types.h>
10 #if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500
12 # define _XOPEN_SOURCE 500
15 # define _GNU_SOURCE 1
17 #if !defined(HAVE_SYS_CDEFS_H) && !defined(HAVE_SYS_FEATURE_TESTS_H)
18 # include <sys/types.h>
24 #ifdef HAVE_EXECINFO_H
25 # include <execinfo.h>
32 #include "stack_trace.h"
35 # undef HAVE_BACKTRACE
41 #ifndef HAVE_BACKTRACE
42 fputs("This platform doesn't support backtrace() yet.\n", stderr
);
45 char **messages
= NULL
;
49 trace_size
= backtrace(trace
, sizeof(trace
) / sizeof(trace
[0]));
50 messages
= backtrace_symbols(trace
, trace_size
);
51 fprintf(stderr
, "======== Stack trace ========\n");
52 for (i
= 1; i
< trace_size
; ++i
) {
53 fprintf(stderr
, "%s\n", messages
[i
]);
60 stack_trace_signal_handler(int sig
, siginfo_t
*info
, void *f
) {
71 stack_trace_on_crash(void)
76 sigemptyset(&act
.sa_mask
);
77 act
.sa_flags
= SA_NODEFER
| SA_ONSTACK
| SA_RESETHAND
| SA_SIGINFO
;
78 act
.sa_sigaction
= stack_trace_signal_handler
;
79 sigaction(SIGABRT
, &act
, NULL
);
80 sigaction(SIGBUS
, &act
, NULL
);
81 sigaction(SIGFPE
, &act
, NULL
);
83 sigaction(SIGILL
, &act
, NULL
);
85 sigaction(SIGSEGV
, &act
, NULL
);
93 # define profile_func_enter(A, B) __cyg_profile_func_enter(A, B)
94 # define profile_func_exit(A, B) __cyg_profile_func_exit(A, B)
97 static unsigned int call_level
= 0U;
100 profile_func_enter(void *this_fn
, void *call_site
)
101 __attribute__((no_instrument_function
));
103 void profile_func_enter(void *this_fn
, void *call_site
)
105 unsigned int level
= 0U;
110 this_fn
= __builtin_return_address(0);
111 if (dladdr(this_fn
, &info
) == 0) {
114 if (info
.dli_sname
!= NULL
&&
115 info
.dli_sname
[0] == '_' && info
.dli_sname
[1] == '_') {
118 while (level
< call_level
) {
122 fputs("┣━━┈", stderr
);
123 if (info
.dli_sname
!= NULL
&& info
.dli_sname
[0] != 0) {
124 fprintf(stderr
, "%s()\n", info
.dli_sname
);
126 fprintf(stderr
, "<%p>()\n", this_fn
);
131 profile_func_exit(void *this_fn
, void *call_site
)
132 __attribute__((no_instrument_function
));
135 profile_func_exit(void *this_fn
, void *call_site
)
139 if (call_level
> 0U) {