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