Commit a1b37d0f37a8941ce78ead019d974c6e75c61be1
1 parent
c35246804f
Exists in
master
assert에 backtrace 추가
원본: https://github.com/mct/junkdrawer/blob/master/c/assert-backtrace.c
Showing
1 changed file
with
66 additions
and
0 deletions
Show diff stats
c/assert-backtrace.c
| @@ -0,0 +1,66 @@ | @@ -0,0 +1,66 @@ | ||
| 1 | +// vim:set ts=4 sw=4 ai et: | ||
| 2 | +#include <stdio.h> | ||
| 3 | +#include <execinfo.h> | ||
| 4 | +#include <signal.h> | ||
| 5 | +#include <stdlib.h> | ||
| 6 | +#include <unistd.h> | ||
| 7 | +#include <assert.h> | ||
| 8 | +/* | ||
| 9 | + | ||
| 10 | +Compile with "-rdynamic" to include function names in the backtrace output | ||
| 11 | + | ||
| 12 | +Example output: | ||
| 13 | + | ||
| 14 | +$ gcc -rdynamic -Werror assert-backtrace.c && ./a.out | ||
| 15 | +Backtrace: | ||
| 16 | + | ||
| 17 | + 1 a.out(quux+0x9) [0x55d540c74cd4] | ||
| 18 | + 2 a.out(qux+0xe) [0x55d540c74d08] | ||
| 19 | + 3 a.out(baz+0xe) [0x55d540c74d19] | ||
| 20 | + 4 a.out(bar+0xe) [0x55d540c74d2a] | ||
| 21 | + 5 a.out(foo+0xe) [0x55d540c74d3b] | ||
| 22 | + 6 a.out(main+0x19) [0x55d540c74d57] | ||
| 23 | + 7 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7) [0x7fdc6b424b97] | ||
| 24 | + 8 a.out(_start+0x2a) [0x55d540c74a5a] | ||
| 25 | + | ||
| 26 | +a.out: assert-backtrace.c:57: quux: Assertion `0 && "test assertion" || printbt()' failed. | ||
| 27 | +Aborted (core dumped) | ||
| 28 | + | ||
| 29 | +*/ | ||
| 30 | + | ||
| 31 | +#define assert_bt(...) assert(__VA_ARGS__ || printbt()) | ||
| 32 | +#define STACK_DEPTH 20 | ||
| 33 | +int printbt(void) | ||
| 34 | +{ | ||
| 35 | + void *buffer[STACK_DEPTH]; | ||
| 36 | + char **strings; | ||
| 37 | + int size, i; | ||
| 38 | + | ||
| 39 | + size = backtrace(buffer, STACK_DEPTH); | ||
| 40 | + strings = backtrace_symbols(buffer, size); | ||
| 41 | + | ||
| 42 | + fprintf(stderr, "Backtrace:\n\n"); | ||
| 43 | + | ||
| 44 | + for (i = 1; i < size; i++) { | ||
| 45 | + if (strings[i][0] == '.' && strings[i][1] == '/') | ||
| 46 | + strings[i] += 2; | ||
| 47 | + | ||
| 48 | + fprintf(stderr, " %3d %s\n", i, strings[i]); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + fprintf(stderr, "\n"); | ||
| 52 | + | ||
| 53 | + return 0; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +void quux() { assert_bt(0 && "test assertion"); } | ||
| 57 | +void qux() { quux(); } | ||
| 58 | +void baz() { qux(); } | ||
| 59 | +void bar() { baz(); } | ||
| 60 | +void foo() { bar(); } | ||
| 61 | + | ||
| 62 | +int main(int argc, char **argv) | ||
| 63 | +{ | ||
| 64 | + foo(); | ||
| 65 | + return 0; | ||
| 66 | +} |