Commit eccd463b authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com
Browse files

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
parent bed1668e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+74 −14
Original line number Diff line number Diff line
@@ -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");
  
static sig_handler write_core(int sig)
  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;
    }

  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;
  sa.sa_handler=handle_segfault;
  sigaction(SIGSEGV, &sa, NULL);
  }
#endif
  (void) sigemptyset(&set);
#ifdef THREAD_SPECIFIC_SIGPIPE
  sigset(SIGPIPE,abort_thread);
+1 −1
Original line number Diff line number Diff line
@@ -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);
}