summaryrefslogtreecommitdiff
path: root/sql/mysqld.cc
diff options
context:
space:
mode:
authorsasha@mysql.sashanet.com <>2000-12-18 11:09:45 -0700
committersasha@mysql.sashanet.com <>2000-12-18 11:09:45 -0700
commiteccd463bd2c45ef90c0e0e2526bbb12ad4569d04 (patch)
tree443950493e879f0459cce1ab3188b62f77ccd30c /sql/mysqld.cc
parentbed1668e238593454c756a1f3f68a4e0be5ec929 (diff)
downloadmariadb-git-eccd463bd2c45ef90c0e0e2526bbb12ad4569d04.tar.gz
fixed logging bug in generate_table()
added message on all segfaults, and numeric backtrace of Linux i386 introduced a bug into ENCRYPT() to test backtrace - will clean up before push, but need this commit locally to pull on slave repositories to do further testing
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r--sql/mysqld.cc88
1 files changed, 74 insertions, 14 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 1f93e6baf67..7e9c6b7cc4c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1038,16 +1038,81 @@ static void init_signals(void)
#else
#ifdef HAVE_LINUXTHREADS
+static sig_handler write_core(int sig);
+#define SIGRETURN_FRAME_COUNT 1
+inline static void trace_stack()
+{
+ uchar **stack_bottom;
+ 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");
+ THD* thd = current_thd;
+ uint frame_count = 0;
+ __asm __volatile__ ("movl %%ebp,%0"
+ :"=r"(ebp)
+ :"r"(ebp));
+ if(!thd)
+ {
+ fprintf(stderr, "Cannot determing thread while backtraing, ebp=%p",
+ ebp);
+ return;
+ }
+ stack_bottom = (uchar**)thd->thread_stack;
+ if(ebp > stack_bottom)
+ {
+ fprintf(stderr, "Bogus stack limit, will not backtrace");
+ return;
+ }
-/* Produce a core for the thread */
+ fprintf(stderr, "stack range sanity check, ok, backtrace follows\n");
+
+ while(ebp < stack_bottom)
+ {
+ uchar** new_ebp = (uchar**)*ebp;
+ fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ?
+ *(ebp+17) : *(ebp+1));
+ if(new_ebp <= ebp)
+ {
+ fprintf(stderr, "New value of ebp failed sanity check\
+terminating backtrace");
+ return;
+ }
+ ebp = new_ebp;
+ ++frame_count;
+ }
-static sig_handler write_core(int sig)
+ fprintf(stderr, "stack trace successful\n");
+}
+#endif
+
+static sig_handler handle_segfault(int sig)
{
fprintf(stderr,"\
-mysqld got signal %s in thread %d; Writing core file: %s\n\
+mysqld got signal %s in thread %d; \n\
The manual section 'Debugging a MySQL server' tells you how to use a \n\
debugger on the core file to produce a backtrace that may help you find out\n\
-why mysqld died\n",sys_siglist[sig],getpid(),mysql_home);
+why mysqld died\n",sys_siglist[sig],getpid());
+#if defined(HAVE_LINUXTHREADS) && defined(__i386__)
+ trace_stack();
+#endif
+#ifdef HAVE_LINUXTHREADS
+ if (test_flags & TEST_CORE_ON_SIGNAL)
+ write_core(sig);
+ else
+ exit(1);
+#else
+ exit(1); /* abort everything */
+#endif
+}
+
+#ifdef HAVE_LINUXTHREADS
+
+/* Produce a core for the thread */
+
+static sig_handler write_core(int sig)
+{
signal(sig, SIG_DFL);
if (fork() != 0) exit(1); // Abort main program
// Core will be written at exit
@@ -1064,16 +1129,11 @@ static void init_signals(void)
sigset(THR_KILL_SIGNAL,end_thread_signal);
sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
-#ifdef HAVE_LINUXTHREADS
- if (test_flags & TEST_CORE_ON_SIGNAL)
- {
- struct sigaction sa; sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
- sa.sa_handler=write_core;
- sigaction(SIGSEGV, &sa, NULL);
- }
-#endif
+ struct sigaction sa; sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
+ sa.sa_handler=handle_segfault;
+ sigaction(SIGSEGV, &sa, NULL);
(void) sigemptyset(&set);
#ifdef THREAD_SPECIFIC_SIGPIPE
sigset(SIGPIPE,abort_thread);