summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sasha@mysql.sashanet.com>2000-12-18 11:09:45 -0700
committerunknown <sasha@mysql.sashanet.com>2000-12-18 11:09:45 -0700
commitb61940f535e36a4e8c8b1f9fb7fa86f1af2bd739 (patch)
tree443950493e879f0459cce1ab3188b62f77ccd30c
parent77a3ea5103f73aac2e3c8868abb2c93c8d01184b (diff)
downloadmariadb-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.cc2
-rw-r--r--sql/mysqld.cc88
-rw-r--r--sql/sql_delete.cc2
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);
}