Commit 666cc691 authored by Gleb Shchepa's avatar Gleb Shchepa

auto merge

parents b870be7b fcaaee63
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#ifdef __WIN__ #ifdef __WIN__
#include <direct.h> #include <direct.h>
#endif #endif
#include <signal.h>
#include <my_stacktrace.h> #include <my_stacktrace.h>
#ifdef __WIN__ #ifdef __WIN__
...@@ -6847,12 +6848,12 @@ void mark_progress(struct st_command* command __attribute__((unused)), ...@@ -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; struct st_connection *conn= cur_con;
fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
my_safe_print_str("read_command_buf", read_command_buf, my_safe_print_str("read_command_buf", read_command_buf,
sizeof(read_command_buf)); sizeof(read_command_buf));
if (conn) if (conn)
...@@ -6866,6 +6867,21 @@ static sig_handler dump_backtrace(int sig) ...@@ -6866,6 +6867,21 @@ static sig_handler dump_backtrace(int sig)
my_print_stacktrace(NULL, my_thread_stack_size); 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__ #ifdef __WIN__
LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
...@@ -6873,7 +6889,7 @@ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) ...@@ -6873,7 +6889,7 @@ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
__try __try
{ {
my_set_exception_pointers(exp); my_set_exception_pointers(exp);
dump_backtrace(exp->ExceptionRecord->ExceptionCode); signal_handler(exp->ExceptionRecord->ExceptionCode);
} }
__except(EXCEPTION_EXECUTE_HANDLER) __except(EXCEPTION_EXECUTE_HANDLER)
{ {
...@@ -6910,13 +6926,15 @@ static void init_signal_handling(void) ...@@ -6910,13 +6926,15 @@ static void init_signal_handling(void)
struct sigaction sa; struct sigaction sa;
DBUG_ENTER("init_signal_handling"); DBUG_ENTER("init_signal_handling");
#ifdef HAVE_STACKTRACE
my_init_stacktrace(); my_init_stacktrace();
#endif
sa.sa_flags = SA_RESETHAND | SA_NODEFER; sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
sa.sa_handler= dump_backtrace; sa.sa_handler= signal_handler;
sigaction(SIGSEGV, &sa, NULL); sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGABRT, &sa, NULL); sigaction(SIGABRT, &sa, NULL);
......
...@@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes; then ...@@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes; then
[Define to 1 if compiler supports weak symbol attribute.]) [Define to 1 if compiler supports weak symbol attribute.])
fi 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_SAVE
AC_LANG_CPLUSPLUS AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(cxxabi.h) AC_CHECK_HEADERS(cxxabi.h)
......
...@@ -27,6 +27,11 @@ ...@@ -27,6 +27,11 @@
#define HAVE_STACKTRACE 1 #define HAVE_STACKTRACE 1
#endif #endif
#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#undef HAVE_STACKTRACE
#define HAVE_STACKTRACE 1
#endif
#if !defined(__NETWARE__) #if !defined(__NETWARE__)
#define HAVE_WRITE_CORE #define HAVE_WRITE_CORE
#endif #endif
......
...@@ -34,11 +34,16 @@ ...@@ -34,11 +34,16 @@
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
static char *heap_start; static char *heap_start;
#ifdef HAVE_BSS_START
extern char *__bss_start; extern char *__bss_start;
#endif
void my_init_stacktrace() void my_init_stacktrace()
{ {
#ifdef HAVE_BSS_START
heap_start = (char*) &__bss_start; heap_start = (char*) &__bss_start;
#endif
} }
void my_safe_print_str(const char* name, const char* val, int max_len) 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) ...@@ -58,55 +63,7 @@ void my_safe_print_str(const char* name, const char* val, int max_len)
fputc('\n', stderr); fputc('\n', stderr);
} }
#ifdef TARGET_OS_LINUX #if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#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 BACKTRACE_DEMANGLE #if BACKTRACE_DEMANGLE
...@@ -144,11 +101,10 @@ static void my_demangle_symbols(char **addrs, int n) ...@@ -144,11 +101,10 @@ static void my_demangle_symbols(char **addrs, int n)
fprintf(stderr, "%s\n", addrs[i]); fprintf(stderr, "%s\n", addrs[i]);
} }
} }
#endif
#endif /* BACKTRACE_DEMANGLE */
#if HAVE_BACKTRACE void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
static void backtrace_current_thread(void)
{ {
void *addrs[128]; void *addrs[128];
char **strings= NULL; char **strings= NULL;
...@@ -167,15 +123,59 @@ static void backtrace_current_thread(void) ...@@ -167,15 +123,59 @@ static void backtrace_current_thread(void)
} }
#endif #endif
} }
#elif defined(TARGET_OS_LINUX)
#ifdef __i386__
#define SIGRETURN_FRAME_OFFSET 17
#endif #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) void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{ {
#if HAVE_BACKTRACE
backtrace_current_thread();
return;
#endif
uchar** fp; uchar** fp;
uint frame_count = 0, sigreturn_frame_count; uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
......
...@@ -2538,7 +2538,9 @@ static void init_signals(void) ...@@ -2538,7 +2538,9 @@ static void init_signals(void)
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
#ifdef HAVE_STACKTRACE
my_init_stacktrace(); my_init_stacktrace();
#endif
#if defined(__amiga__) #if defined(__amiga__)
sa.sa_handler=(void(*)())handle_segfault; sa.sa_handler=(void(*)())handle_segfault;
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment