Commit d63b8290 authored by unknown's avatar unknown

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.
parent 6fc748e3
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
......
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