Commit 56ef6a23 authored by Gleb Shchepa's avatar Gleb Shchepa
Browse files

auto merge

parents e2d1351b e7f3c5fc
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -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* command __attribute__((unused)),

}

#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 sig)
  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_POINTERS *exp)
  __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);
+11 −0
Original line number Diff line number Diff line
@@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes; then
            [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)
+5 −0
Original line number Diff line number Diff line
@@ -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
+56 −56
Original line number Diff line number Diff line
@@ -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, const char* val, int max_len)
  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 **addrs, int n)
      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(void)
  }
#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__)
+2 −0
Original line number Diff line number Diff line
@@ -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