summaryrefslogtreecommitdiff
path: root/mysys/stacktrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/stacktrace.c')
-rw-r--r--mysys/stacktrace.c112
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__)