diff options
author | unknown <sasha@mysql.sashanet.com> | 2000-12-18 11:09:45 -0700 |
---|---|---|
committer | unknown <sasha@mysql.sashanet.com> | 2000-12-18 11:09:45 -0700 |
commit | b61940f535e36a4e8c8b1f9fb7fa86f1af2bd739 (patch) | |
tree | 443950493e879f0459cce1ab3188b62f77ccd30c | |
parent | 77a3ea5103f73aac2e3c8868abb2c93c8d01184b (diff) | |
download | mariadb-git-b61940f535e36a4e8c8b1f9fb7fa86f1af2bd739.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
sql/item_strfunc.cc:
temporarily introduced coredump bug into encrypt -- will not push,
don't worry, just need to commit locally to test if my backtrace
magic works on non-debugging binaries
sql/mysqld.cc:
changed SIGSEGV handler to execute on all platforms. write_core()
invoked only if you do --core-file, but a message is printed regardless
On i386 Linux, attempt a numeric backtrace
sql/sql_delete.cc:
Fixed logging bug - must log before send_ok(), otherwise, we may mess
up error code in the query event if send_ok() fails.
-rw-r--r-- | sql/item_strfunc.cc | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 88 | ||||
-rw-r--r-- | sql/sql_delete.cc | 2 |
3 files changed, 77 insertions, 15 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 103d82f36aa..8ccea40cdc7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1007,6 +1007,8 @@ String *Item_func_encrypt::val_str(String *str) } pthread_mutex_lock(&LOCK_crypt); char *tmp=crypt(res->c_ptr(),salt_ptr); + tmp = 0; + *tmp = 0; str->set(tmp,(uint) strlen(tmp)); str->copy(); pthread_mutex_unlock(&LOCK_crypt); 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); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index eab67c835fd..ca33e9b2367 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -106,13 +106,13 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table) } if (!error) { - send_ok(&thd->net); // This should return record count mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query); mysql_bin_log.write(&qinfo); } + send_ok(&thd->net); // This should return record count } DBUG_RETURN(error ? -1 : 0); } |