summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sasha@mysql.sashanet.com>2000-12-19 07:56:24 -0700
committerunknown <sasha@mysql.sashanet.com>2000-12-19 07:56:24 -0700
commitbadb90fd8408498052f571faceba3bcc47433082 (patch)
treecab5519239696c2c2a8375d45c006b5e2c2597d3
parentb61940f535e36a4e8c8b1f9fb7fa86f1af2bd739 (diff)
downloadmariadb-git-badb90fd8408498052f571faceba3bcc47433082.tar.gz
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
-rw-r--r--sql/mysqld.cc31
1 files changed, 24 insertions, 7 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7e9c6b7cc4c..25229191236 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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;
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
FILE *bootstrap_file=0;
+int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
extern MASTER_INFO glob_mi;
extern int init_master_info(MASTER_INFO* mi);
@@ -1039,6 +1040,7 @@ static void init_signals(void)
#ifdef HAVE_LINUXTHREADS
static sig_handler write_core(int sig);
+#ifdef __i386__
#define SIGRETURN_FRAME_COUNT 1
inline static void trace_stack()
{
@@ -1046,23 +1048,30 @@ inline static void trace_stack()
uchar** ebp;
LINT_INIT(ebp);
fprintf(stderr, "Attemping backtrace, please send the info below to\
-bugs@lists.mysql.com. If you see no messages after this, something is \
-went terribly wrong - report this anyway\n");
+ bugs@lists.mysql.com. If you see no messages after this, something \
+ went terribly wrong - report this anyway\n");
THD* thd = current_thd;
uint frame_count = 0;
__asm __volatile__ ("movl %%ebp,%0"
:"=r"(ebp)
:"r"(ebp));
+ if(!ebp)
+ {
+ fprintf(stderr, "Stack is a mess, frame pointer (ebp) is NULL,\
+ aborting backtrace\n");
+ return;
+ }
if(!thd)
{
- fprintf(stderr, "Cannot determing thread while backtraing, ebp=%p",
+ fprintf(stderr, "Cannot determine thread, ebp=%p, aborting backtrace\n",
ebp);
return;
}
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;
}
@@ -1073,10 +1082,10 @@ went terribly wrong - report this anyway\n");
uchar** new_ebp = (uchar**)*ebp;
fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ?
*(ebp+17) : *(ebp+1));
- if(new_ebp <= ebp)
+ if(new_ebp <= ebp )
{
fprintf(stderr, "New value of ebp failed sanity check\
-terminating backtrace");
+terminating backtrace\n");
return;
}
ebp = new_ebp;
@@ -1086,9 +1095,17 @@ terminating backtrace");
fprintf(stderr, "stack trace successful\n");
}
#endif
+#endif
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,"\
mysqld got signal %s in thread %d; \n\
The manual section 'Debugging a MySQL server' tells you how to use a \n\