List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:June 19 2008 4:02pm
Subject:bzr commit into mysql-5.1 branch (davi:2669) Bug#37003
View as plain text  
# At a local mysql-5.1 repository of davi

 2669 Davi Arnaut	2008-06-19
      Bug#37003 Tests sporadically crashes with embedded server
      
      Another problem is that the backtrace facility wasn't being
      enabled for non-Linux targets even if the target OS has the
      backtrace functions. Also, the stacktrace functions inside
      mysqltest were being used without proper checks for their
      presence in the build.
modified:
  client/mysqltest.c
  configure.in
  include/my_stacktrace.h
  mysys/stacktrace.c
  sql/mysqld.cc

per-file messages:
  client/mysqltest.c
    Only use stacktrace functions if they are available.
  configure.in
    Check if the compiler defines __bss_start
  include/my_stacktrace.h
    Enable stacktrace if system has backtrace functions.
  mysys/stacktrace.c
    Use backtrace functions if the system supports it.
  sql/mysqld.cc
    Only use stacktrace functions if they are available.
=== modified file 'client/mysqltest.c'
--- a/client/mysqltest.c	2008-06-18 16:17:15 +0000
+++ b/client/mysqltest.c	2008-06-19 14:02:32 +0000
@@ -48,6 +48,7 @@
 #ifdef __WIN__
 #include <direct.h>
 #endif
+#include <signal.h>
 #include <my_stacktrace.h>
 
 #ifdef __WIN__
@@ -6847,12 +6848,12 @@ void mark_progress(struct st_command* co
 
 }
 
+#ifdef HAVE_STACKTRACE
 
-static sig_handler dump_backtrace(int sig)
+static void dump_backtrace(void)
 {
   struct st_connection *conn= cur_con;
 
-  fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
   my_safe_print_str("read_command_buf", read_command_buf,
                     sizeof(read_command_buf));
   if (conn)
@@ -6866,6 +6867,21 @@ static sig_handler dump_backtrace(int si
   my_print_stacktrace(NULL, my_thread_stack_size);
 }
 
+#else
+
+static void dump_backtrace(void)
+{
+  fputs("Backtrace not available.\n", stderr);
+}
+
+#endif
+
+static sig_handler signal_handler(int sig)
+{
+  fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
+  dump_backtrace();
+}
+
 #ifdef __WIN__
 
 LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
@@ -6873,7 +6889,7 @@ LONG WINAPI exception_filter(EXCEPTION_P
   __try
   {
     my_set_exception_pointers(exp);
-    dump_backtrace(exp->ExceptionRecord->ExceptionCode);
+    signal_handler(exp->ExceptionRecord->ExceptionCode);
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
@@ -6910,13 +6926,15 @@ static void init_signal_handling(void)
   struct sigaction sa;
   DBUG_ENTER("init_signal_handling");
 
+#ifdef HAVE_STACKTRACE
   my_init_stacktrace();
+#endif
 
   sa.sa_flags = SA_RESETHAND | SA_NODEFER;
   sigemptyset(&sa.sa_mask);
   sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
 
-  sa.sa_handler= dump_backtrace;
+  sa.sa_handler= signal_handler;
 
   sigaction(SIGSEGV, &sa, NULL);
   sigaction(SIGABRT, &sa, NULL);

=== modified file 'configure.in'
--- a/configure.in	2008-06-18 16:17:15 +0000
+++ b/configure.in	2008-06-19 14:02:32 +0000
@@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes;
             [Define to 1 if compiler supports weak symbol attribute.])
 fi
 
+AC_CACHE_CHECK([whether __bss_start is defined], mysql_cv_bss_start,
+[AC_TRY_LINK([],[
+  extern char *__bss_start;
+  return __bss_start ? 1 : 0;
+], [mysql_cv_bss_start=yes], [mysql_cv_bss_start=no])])
+
+if test "x$mysql_cv_bss_start" = xyes; then
+  AC_DEFINE(HAVE_BSS_START, 1,
+            [Define to 1 if compiler defines __bss_start.])
+fi
+
 AC_LANG_SAVE
 AC_LANG_CPLUSPLUS
 AC_CHECK_HEADERS(cxxabi.h)

=== modified file 'include/my_stacktrace.h'
--- a/include/my_stacktrace.h	2008-06-18 16:17:15 +0000
+++ b/include/my_stacktrace.h	2008-06-19 14:02:32 +0000
@@ -27,6 +27,11 @@
 #define HAVE_STACKTRACE 1
 #endif
 
+#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
+#undef HAVE_STACKTRACE
+#define HAVE_STACKTRACE 1
+#endif
+
 #if !defined(__NETWARE__)
 #define HAVE_WRITE_CORE
 #endif

=== modified file 'mysys/stacktrace.c'
--- a/mysys/stacktrace.c	2008-06-18 16:17:15 +0000
+++ b/mysys/stacktrace.c	2008-06-19 14:02:32 +0000
@@ -34,11 +34,16 @@
 #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p)
<= heap_end)
 
 static char *heap_start;
+
+#ifdef HAVE_BSS_START
 extern char *__bss_start;
+#endif
 
 void my_init_stacktrace()
 {
+#ifdef HAVE_BSS_START
   heap_start = (char*) &__bss_start;
+#endif
 }
 
 void my_safe_print_str(const char* name, const char* val, int max_len)
@@ -58,55 +63,7 @@ void my_safe_print_str(const char* name,
   fputc('\n', stderr);
 }
 
-#ifdef TARGET_OS_LINUX
-
-#ifdef __i386__
-#define SIGRETURN_FRAME_OFFSET 17
-#endif
-
-#ifdef __x86_64__
-#define SIGRETURN_FRAME_OFFSET 23
-#endif
-
-#if defined(__alpha__) && defined(__GNUC__)
-/*
-  The only way to backtrace without a symbol table on alpha
-  is to find stq fp,N(sp), and the first byte
-  of the instruction opcode will give us the value of N. From this
-  we can find where the old value of fp is stored
-*/
-
-#define MAX_INSTR_IN_FUNC  10000
-
-inline uchar** find_prev_fp(uint32* pc, uchar** fp)
-{
-  int i;
-  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
-  {
-    uchar* p = (uchar*)pc;
-    if (p[2] == 222 &&  p[3] == 35)
-    {
-      return (uchar**)((uchar*)fp - *(short int*)p);
-    }
-  }
-  return 0;
-}
-
-inline uint32* find_prev_pc(uint32* pc, uchar** fp)
-{
-  int i;
-  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
-  {
-    char* p = (char*)pc;
-    if (p[1] == 0 && p[2] == 94 &&  p[3] == -73)
-    {
-      uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
-      return prev_pc;
-    }
-  }
-  return 0;
-}
-#endif /* defined(__alpha__) && defined(__GNUC__) */
+#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
 
 #if BACKTRACE_DEMANGLE
 
@@ -144,11 +101,10 @@ static void my_demangle_symbols(char **a
       fprintf(stderr, "%s\n", addrs[i]);
   }
 }
-#endif
 
+#endif /* BACKTRACE_DEMANGLE */
 
-#if HAVE_BACKTRACE
-static void backtrace_current_thread(void)
+void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
 {
   void *addrs[128];
   char **strings= NULL;
@@ -167,15 +123,59 @@ static void backtrace_current_thread(voi
   }
 #endif
 }
+
+#elif defined(TARGET_OS_LINUX)
+
+#ifdef __i386__
+#define SIGRETURN_FRAME_OFFSET 17
 #endif
 
+#ifdef __x86_64__
+#define SIGRETURN_FRAME_OFFSET 23
+#endif
+
+#if defined(__alpha__) && defined(__GNUC__)
+/*
+  The only way to backtrace without a symbol table on alpha
+  is to find stq fp,N(sp), and the first byte
+  of the instruction opcode will give us the value of N. From this
+  we can find where the old value of fp is stored
+*/
+
+#define MAX_INSTR_IN_FUNC  10000
+
+inline uchar** find_prev_fp(uint32* pc, uchar** fp)
+{
+  int i;
+  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
+  {
+    uchar* p = (uchar*)pc;
+    if (p[2] == 222 &&  p[3] == 35)
+    {
+      return (uchar**)((uchar*)fp - *(short int*)p);
+    }
+  }
+  return 0;
+}
+
+inline uint32* find_prev_pc(uint32* pc, uchar** fp)
+{
+  int i;
+  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
+  {
+    char* p = (char*)pc;
+    if (p[1] == 0 && p[2] == 94 &&  p[3] == -73)
+    {
+      uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
+      return prev_pc;
+    }
+  }
+  return 0;
+}
+#endif /* defined(__alpha__) && defined(__GNUC__) */
 
 void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
 {
-#if HAVE_BACKTRACE
-  backtrace_current_thread();
-  return;
-#endif
   uchar** fp;
   uint frame_count = 0, sigreturn_frame_count;
 #if defined(__alpha__) && defined(__GNUC__)

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-06-18 16:17:15 +0000
+++ b/sql/mysqld.cc	2008-06-19 14:02:32 +0000
@@ -2538,7 +2538,9 @@ static void init_signals(void)
     sigemptyset(&sa.sa_mask);
     sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
 
+#ifdef HAVE_STACKTRACE
     my_init_stacktrace();
+#endif
 #if defined(__amiga__)
     sa.sa_handler=(void(*)())handle_segfault;
 #else

Thread
bzr commit into mysql-5.1 branch (davi:2669) Bug#37003Davi Arnaut19 Jun