Loading client/mysqltest.c +22 −4 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #ifdef __WIN__ #include <direct.h> #endif #include <signal.h> #include <my_stacktrace.h> #ifdef __WIN__ Loading Loading @@ -6847,12 +6848,12 @@ void mark_progress(struct st_command* command __attribute__((unused)), } #ifdef HAVE_STACKTRACE static sig_handler dump_backtrace(int sig) static void dump_backtrace(void) { struct st_connection *conn= cur_con; fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig); my_safe_print_str("read_command_buf", read_command_buf, sizeof(read_command_buf)); if (conn) Loading @@ -6866,6 +6867,21 @@ static sig_handler dump_backtrace(int sig) my_print_stacktrace(NULL, my_thread_stack_size); } #else static void dump_backtrace(void) { fputs("Backtrace not available.\n", stderr); } #endif static sig_handler signal_handler(int sig) { fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig); dump_backtrace(); } #ifdef __WIN__ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) Loading @@ -6873,7 +6889,7 @@ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) __try { my_set_exception_pointers(exp); dump_backtrace(exp->ExceptionRecord->ExceptionCode); signal_handler(exp->ExceptionRecord->ExceptionCode); } __except(EXCEPTION_EXECUTE_HANDLER) { Loading Loading @@ -6910,13 +6926,15 @@ static void init_signal_handling(void) struct sigaction sa; DBUG_ENTER("init_signal_handling"); #ifdef HAVE_STACKTRACE my_init_stacktrace(); #endif sa.sa_flags = SA_RESETHAND | SA_NODEFER; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); sa.sa_handler= dump_backtrace; sa.sa_handler= signal_handler; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGABRT, &sa, NULL); Loading configure.in +11 −0 Original line number Diff line number Diff line Loading @@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes; then [Define to 1 if compiler supports weak symbol attribute.]) fi AC_CACHE_CHECK([whether __bss_start is defined], mysql_cv_bss_start, [AC_TRY_LINK([],[ extern char *__bss_start; return __bss_start ? 1 : 0; ], [mysql_cv_bss_start=yes], [mysql_cv_bss_start=no])]) if test "x$mysql_cv_bss_start" = xyes; then AC_DEFINE(HAVE_BSS_START, 1, [Define to 1 if compiler defines __bss_start.]) fi AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_CHECK_HEADERS(cxxabi.h) Loading include/my_stacktrace.h +5 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ #define HAVE_STACKTRACE 1 #endif #if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) #undef HAVE_STACKTRACE #define HAVE_STACKTRACE 1 #endif #if !defined(__NETWARE__) #define HAVE_WRITE_CORE #endif Loading mysys/stacktrace.c +56 −56 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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 Loading Loading @@ -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; Loading @@ -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__) Loading sql/mysqld.cc +2 −0 Original line number Diff line number Diff line Loading @@ -2538,7 +2538,9 @@ static void init_signals(void) sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); #ifdef HAVE_STACKTRACE my_init_stacktrace(); #endif #if defined(__amiga__) sa.sa_handler=(void(*)())handle_segfault; #else Loading Loading
client/mysqltest.c +22 −4 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #ifdef __WIN__ #include <direct.h> #endif #include <signal.h> #include <my_stacktrace.h> #ifdef __WIN__ Loading Loading @@ -6847,12 +6848,12 @@ void mark_progress(struct st_command* command __attribute__((unused)), } #ifdef HAVE_STACKTRACE static sig_handler dump_backtrace(int sig) static void dump_backtrace(void) { struct st_connection *conn= cur_con; fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig); my_safe_print_str("read_command_buf", read_command_buf, sizeof(read_command_buf)); if (conn) Loading @@ -6866,6 +6867,21 @@ static sig_handler dump_backtrace(int sig) my_print_stacktrace(NULL, my_thread_stack_size); } #else static void dump_backtrace(void) { fputs("Backtrace not available.\n", stderr); } #endif static sig_handler signal_handler(int sig) { fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig); dump_backtrace(); } #ifdef __WIN__ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) Loading @@ -6873,7 +6889,7 @@ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) __try { my_set_exception_pointers(exp); dump_backtrace(exp->ExceptionRecord->ExceptionCode); signal_handler(exp->ExceptionRecord->ExceptionCode); } __except(EXCEPTION_EXECUTE_HANDLER) { Loading Loading @@ -6910,13 +6926,15 @@ static void init_signal_handling(void) struct sigaction sa; DBUG_ENTER("init_signal_handling"); #ifdef HAVE_STACKTRACE my_init_stacktrace(); #endif sa.sa_flags = SA_RESETHAND | SA_NODEFER; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); sa.sa_handler= dump_backtrace; sa.sa_handler= signal_handler; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGABRT, &sa, NULL); Loading
configure.in +11 −0 Original line number Diff line number Diff line Loading @@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes; then [Define to 1 if compiler supports weak symbol attribute.]) fi AC_CACHE_CHECK([whether __bss_start is defined], mysql_cv_bss_start, [AC_TRY_LINK([],[ extern char *__bss_start; return __bss_start ? 1 : 0; ], [mysql_cv_bss_start=yes], [mysql_cv_bss_start=no])]) if test "x$mysql_cv_bss_start" = xyes; then AC_DEFINE(HAVE_BSS_START, 1, [Define to 1 if compiler defines __bss_start.]) fi AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_CHECK_HEADERS(cxxabi.h) Loading
include/my_stacktrace.h +5 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ #define HAVE_STACKTRACE 1 #endif #if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) #undef HAVE_STACKTRACE #define HAVE_STACKTRACE 1 #endif #if !defined(__NETWARE__) #define HAVE_WRITE_CORE #endif Loading
mysys/stacktrace.c +56 −56 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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 Loading Loading @@ -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; Loading @@ -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__) Loading
sql/mysqld.cc +2 −0 Original line number Diff line number Diff line Loading @@ -2538,7 +2538,9 @@ static void init_signals(void) sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); #ifdef HAVE_STACKTRACE my_init_stacktrace(); #endif #if defined(__amiga__) sa.sa_handler=(void(*)())handle_segfault; #else Loading