diff options
Diffstat (limited to 'mysys/stacktrace.c')
-rw-r--r-- | mysys/stacktrace.c | 112 |
1 files changed, 56 insertions, 56 deletions
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 7466dcb416e..9ae3d88ef50 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -34,11 +34,16 @@ #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) static char *heap_start; + +#ifdef HAVE_BSS_START extern char *__bss_start; +#endif void my_init_stacktrace() { +#ifdef HAVE_BSS_START heap_start = (char*) &__bss_start; +#endif } void my_safe_print_str(const char* name, const char* val, int max_len) @@ -58,55 +63,7 @@ void my_safe_print_str(const char* name, const char* val, int max_len) fputc('\n', stderr); } -#ifdef TARGET_OS_LINUX - -#ifdef __i386__ -#define SIGRETURN_FRAME_OFFSET 17 -#endif - -#ifdef __x86_64__ -#define SIGRETURN_FRAME_OFFSET 23 -#endif - -#if defined(__alpha__) && defined(__GNUC__) -/* - The only way to backtrace without a symbol table on alpha - is to find stq fp,N(sp), and the first byte - of the instruction opcode will give us the value of N. From this - we can find where the old value of fp is stored -*/ - -#define MAX_INSTR_IN_FUNC 10000 - -inline uchar** find_prev_fp(uint32* pc, uchar** fp) -{ - int i; - for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) - { - uchar* p = (uchar*)pc; - if (p[2] == 222 && p[3] == 35) - { - return (uchar**)((uchar*)fp - *(short int*)p); - } - } - return 0; -} - -inline uint32* find_prev_pc(uint32* pc, uchar** fp) -{ - int i; - for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) - { - char* p = (char*)pc; - if (p[1] == 0 && p[2] == 94 && p[3] == -73) - { - uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp))); - return prev_pc; - } - } - return 0; -} -#endif /* defined(__alpha__) && defined(__GNUC__) */ +#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) #if BACKTRACE_DEMANGLE @@ -144,11 +101,10 @@ static void my_demangle_symbols(char **addrs, int n) fprintf(stderr, "%s\n", addrs[i]); } } -#endif +#endif /* BACKTRACE_DEMANGLE */ -#if HAVE_BACKTRACE -static void backtrace_current_thread(void) +void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { void *addrs[128]; char **strings= NULL; @@ -167,15 +123,59 @@ static void backtrace_current_thread(void) } #endif } + +#elif defined(TARGET_OS_LINUX) + +#ifdef __i386__ +#define SIGRETURN_FRAME_OFFSET 17 #endif +#ifdef __x86_64__ +#define SIGRETURN_FRAME_OFFSET 23 +#endif + +#if defined(__alpha__) && defined(__GNUC__) +/* + The only way to backtrace without a symbol table on alpha + is to find stq fp,N(sp), and the first byte + of the instruction opcode will give us the value of N. From this + we can find where the old value of fp is stored +*/ + +#define MAX_INSTR_IN_FUNC 10000 + +inline uchar** find_prev_fp(uint32* pc, uchar** fp) +{ + int i; + for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) + { + uchar* p = (uchar*)pc; + if (p[2] == 222 && p[3] == 35) + { + return (uchar**)((uchar*)fp - *(short int*)p); + } + } + return 0; +} + +inline uint32* find_prev_pc(uint32* pc, uchar** fp) +{ + int i; + for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) + { + char* p = (char*)pc; + if (p[1] == 0 && p[2] == 94 && p[3] == -73) + { + uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp))); + return prev_pc; + } + } + return 0; +} +#endif /* defined(__alpha__) && defined(__GNUC__) */ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { -#if HAVE_BACKTRACE - backtrace_current_thread(); - return; -#endif uchar** fp; uint frame_count = 0, sigreturn_frame_count; #if defined(__alpha__) && defined(__GNUC__) |