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