Commit badb90fd authored by unknown's avatar unknown

fixes for backtracing, still will not push, just a local commit


sql/mysqld.cc:
  trace_stack() should only be compiled if we are x86
  make segfault handler "re-enterant" in case we sefault in the
  handler itself
  fixed typos
parent b61940f5
...@@ -159,6 +159,7 @@ static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, ...@@ -159,6 +159,7 @@ static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4;
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0; bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
FILE *bootstrap_file=0; FILE *bootstrap_file=0;
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
extern MASTER_INFO glob_mi; extern MASTER_INFO glob_mi;
extern int init_master_info(MASTER_INFO* mi); extern int init_master_info(MASTER_INFO* mi);
...@@ -1039,6 +1040,7 @@ static void init_signals(void) ...@@ -1039,6 +1040,7 @@ static void init_signals(void)
#ifdef HAVE_LINUXTHREADS #ifdef HAVE_LINUXTHREADS
static sig_handler write_core(int sig); static sig_handler write_core(int sig);
#ifdef __i386__
#define SIGRETURN_FRAME_COUNT 1 #define SIGRETURN_FRAME_COUNT 1
inline static void trace_stack() inline static void trace_stack()
{ {
...@@ -1046,23 +1048,30 @@ inline static void trace_stack() ...@@ -1046,23 +1048,30 @@ inline static void trace_stack()
uchar** ebp; uchar** ebp;
LINT_INIT(ebp); LINT_INIT(ebp);
fprintf(stderr, "Attemping backtrace, please send the info below to\ fprintf(stderr, "Attemping backtrace, please send the info below to\
bugs@lists.mysql.com. If you see no messages after this, something is \ bugs@lists.mysql.com. If you see no messages after this, something \
went terribly wrong - report this anyway\n"); went terribly wrong - report this anyway\n");
THD* thd = current_thd; THD* thd = current_thd;
uint frame_count = 0; uint frame_count = 0;
__asm __volatile__ ("movl %%ebp,%0" __asm __volatile__ ("movl %%ebp,%0"
:"=r"(ebp) :"=r"(ebp)
:"r"(ebp)); :"r"(ebp));
if(!ebp)
{
fprintf(stderr, "Stack is a mess, frame pointer (ebp) is NULL,\
aborting backtrace\n");
return;
}
if(!thd) if(!thd)
{ {
fprintf(stderr, "Cannot determing thread while backtraing, ebp=%p", fprintf(stderr, "Cannot determine thread, ebp=%p, aborting backtrace\n",
ebp); ebp);
return; return;
} }
stack_bottom = (uchar**)thd->thread_stack; stack_bottom = (uchar**)thd->thread_stack;
if(ebp > stack_bottom) if(ebp > stack_bottom || ebp < stack_bottom - thread_stack)
{ {
fprintf(stderr, "Bogus stack limit, will not backtrace"); fprintf(stderr,
"Bogus stack limit or frame pointer, aborting backtrace\n");
return; return;
} }
...@@ -1073,10 +1082,10 @@ went terribly wrong - report this anyway\n"); ...@@ -1073,10 +1082,10 @@ went terribly wrong - report this anyway\n");
uchar** new_ebp = (uchar**)*ebp; uchar** new_ebp = (uchar**)*ebp;
fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ? fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ?
*(ebp+17) : *(ebp+1)); *(ebp+17) : *(ebp+1));
if(new_ebp <= ebp) if(new_ebp <= ebp )
{ {
fprintf(stderr, "New value of ebp failed sanity check\ fprintf(stderr, "New value of ebp failed sanity check\
terminating backtrace"); terminating backtrace\n");
return; return;
} }
ebp = new_ebp; ebp = new_ebp;
...@@ -1086,9 +1095,17 @@ terminating backtrace"); ...@@ -1086,9 +1095,17 @@ terminating backtrace");
fprintf(stderr, "stack trace successful\n"); fprintf(stderr, "stack trace successful\n");
} }
#endif #endif
#endif
static sig_handler handle_segfault(int sig) static sig_handler handle_segfault(int sig)
{ {
// strictly speaking, one needs a mutex here
// but since we have got SIGSEGV already, things are a mess
// so not having the mutex is not as bad as possibly using a buggy
// mutex - so we keep things simple
if(segfaulted)
return;
segfaulted = 1;
fprintf(stderr,"\ fprintf(stderr,"\
mysqld got signal %s in thread %d; \n\ mysqld got signal %s in thread %d; \n\
The manual section 'Debugging a MySQL server' tells you how to use a \n\ The manual section 'Debugging a MySQL server' tells you how to use a \n\
......
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