1 #include <libcflat.h> 2 #include <stack.h> 3 4 #define MAX_DEPTH 20 5 6 static void print_stack(const void **return_addrs, int depth, 7 bool top_is_return_address) 8 { 9 int i = 0; 10 11 printf("\tSTACK:"); 12 13 /* @addr indicates a non-return address, as expected by the stack 14 * pretty printer script. */ 15 if (depth > 0 && !top_is_return_address) { 16 printf(" @%lx", (unsigned long) return_addrs[0]); 17 i++; 18 } 19 20 for (; i < depth; i++) { 21 printf(" %lx", (unsigned long) return_addrs[i]); 22 } 23 printf("\n"); 24 } 25 26 void dump_stack(void) 27 { 28 const void *return_addrs[MAX_DEPTH]; 29 int depth; 30 31 depth = backtrace(return_addrs, MAX_DEPTH); 32 print_stack(&return_addrs[1], depth ? depth - 1 : 0, true); 33 } 34 35 void dump_frame_stack(const void *instruction, const void *frame) 36 { 37 const void *return_addrs[MAX_DEPTH]; 38 int depth; 39 40 return_addrs[0] = instruction; 41 depth = backtrace_frame(frame, &return_addrs[1], MAX_DEPTH - 1); 42 print_stack(return_addrs, depth + 1, false); 43 } 44 45 #ifndef HAVE_ARCH_BACKTRACE 46 int backtrace(const void **return_addrs, int max_depth) 47 { 48 static int walking; 49 int depth = 0; 50 void *addr; 51 52 if (walking) { 53 printf("RECURSIVE STACK WALK!!!\n"); 54 return 0; 55 } 56 walking = 1; 57 58 /* __builtin_return_address requires a compile-time constant argument */ 59 #define GET_RETURN_ADDRESS(i) \ 60 if (max_depth == i) \ 61 goto done; \ 62 addr = __builtin_return_address(i); \ 63 if (!addr) \ 64 goto done; \ 65 return_addrs[i] = __builtin_extract_return_addr(addr); \ 66 depth = i + 1; \ 67 68 GET_RETURN_ADDRESS(0) 69 GET_RETURN_ADDRESS(1) 70 GET_RETURN_ADDRESS(2) 71 GET_RETURN_ADDRESS(3) 72 GET_RETURN_ADDRESS(4) 73 GET_RETURN_ADDRESS(5) 74 GET_RETURN_ADDRESS(6) 75 GET_RETURN_ADDRESS(7) 76 GET_RETURN_ADDRESS(8) 77 GET_RETURN_ADDRESS(9) 78 GET_RETURN_ADDRESS(10) 79 GET_RETURN_ADDRESS(11) 80 GET_RETURN_ADDRESS(12) 81 GET_RETURN_ADDRESS(13) 82 GET_RETURN_ADDRESS(14) 83 GET_RETURN_ADDRESS(15) 84 GET_RETURN_ADDRESS(16) 85 GET_RETURN_ADDRESS(17) 86 GET_RETURN_ADDRESS(18) 87 GET_RETURN_ADDRESS(19) 88 GET_RETURN_ADDRESS(20) 89 90 #undef GET_RETURN_ADDRESS 91 92 done: 93 walking = 0; 94 return depth; 95 } 96 #endif /* HAVE_ARCH_BACKTRACE */ 97