mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
@ -48,6 +48,7 @@
|
|||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <signal.h>
|
||||||
#include <my_stacktrace.h>
|
#include <my_stacktrace.h>
|
||||||
|
|
||||||
#ifdef __WIN__
|
#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;
|
struct st_connection *conn= cur_con;
|
||||||
|
|
||||||
fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
|
|
||||||
my_safe_print_str("read_command_buf", read_command_buf,
|
my_safe_print_str("read_command_buf", read_command_buf,
|
||||||
sizeof(read_command_buf));
|
sizeof(read_command_buf));
|
||||||
if (conn)
|
if (conn)
|
||||||
@ -6866,6 +6867,21 @@ static sig_handler dump_backtrace(int sig)
|
|||||||
my_print_stacktrace(NULL, my_thread_stack_size);
|
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__
|
#ifdef __WIN__
|
||||||
|
|
||||||
LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
|
LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
|
||||||
@ -6873,7 +6889,7 @@ LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
|
|||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
my_set_exception_pointers(exp);
|
my_set_exception_pointers(exp);
|
||||||
dump_backtrace(exp->ExceptionRecord->ExceptionCode);
|
signal_handler(exp->ExceptionRecord->ExceptionCode);
|
||||||
}
|
}
|
||||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
@ -6910,13 +6926,15 @@ static void init_signal_handling(void)
|
|||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
DBUG_ENTER("init_signal_handling");
|
DBUG_ENTER("init_signal_handling");
|
||||||
|
|
||||||
|
#ifdef HAVE_STACKTRACE
|
||||||
my_init_stacktrace();
|
my_init_stacktrace();
|
||||||
|
#endif
|
||||||
|
|
||||||
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
|
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
|
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
|
||||||
|
|
||||||
sa.sa_handler= dump_backtrace;
|
sa.sa_handler= signal_handler;
|
||||||
|
|
||||||
sigaction(SIGSEGV, &sa, NULL);
|
sigaction(SIGSEGV, &sa, NULL);
|
||||||
sigaction(SIGABRT, &sa, NULL);
|
sigaction(SIGABRT, &sa, NULL);
|
||||||
|
11
configure.in
11
configure.in
@ -2351,6 +2351,17 @@ if test "x$mysql_cv_weak_symbol" = xyes; then
|
|||||||
[Define to 1 if compiler supports weak symbol attribute.])
|
[Define to 1 if compiler supports weak symbol attribute.])
|
||||||
fi
|
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_SAVE
|
||||||
AC_LANG_CPLUSPLUS
|
AC_LANG_CPLUSPLUS
|
||||||
AC_CHECK_HEADERS(cxxabi.h)
|
AC_CHECK_HEADERS(cxxabi.h)
|
||||||
|
@ -27,6 +27,11 @@
|
|||||||
#define HAVE_STACKTRACE 1
|
#define HAVE_STACKTRACE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
|
||||||
|
#undef HAVE_STACKTRACE
|
||||||
|
#define HAVE_STACKTRACE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(__NETWARE__)
|
#if !defined(__NETWARE__)
|
||||||
#define HAVE_WRITE_CORE
|
#define HAVE_WRITE_CORE
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,11 +34,16 @@
|
|||||||
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
|
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
|
||||||
|
|
||||||
static char *heap_start;
|
static char *heap_start;
|
||||||
|
|
||||||
|
#ifdef HAVE_BSS_START
|
||||||
extern char *__bss_start;
|
extern char *__bss_start;
|
||||||
|
#endif
|
||||||
|
|
||||||
void my_init_stacktrace()
|
void my_init_stacktrace()
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_BSS_START
|
||||||
heap_start = (char*) &__bss_start;
|
heap_start = (char*) &__bss_start;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_safe_print_str(const char* name, const char* val, int max_len)
|
void my_safe_print_str(const char* name, const char* val, int max_len)
|
||||||
@ -58,7 +63,68 @@ void my_safe_print_str(const char* name, const char* val, int max_len)
|
|||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TARGET_OS_LINUX
|
#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
|
||||||
|
|
||||||
|
#if BACKTRACE_DEMANGLE
|
||||||
|
|
||||||
|
char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void my_demangle_symbols(char **addrs, int n)
|
||||||
|
{
|
||||||
|
int status, i;
|
||||||
|
char *begin, *end, *demangled;
|
||||||
|
|
||||||
|
for (i= 0; i < n; i++)
|
||||||
|
{
|
||||||
|
demangled= NULL;
|
||||||
|
begin= strchr(addrs[i], '(');
|
||||||
|
end= begin ? strchr(begin, '+') : NULL;
|
||||||
|
|
||||||
|
if (begin && end)
|
||||||
|
{
|
||||||
|
*begin++= *end++= '\0';
|
||||||
|
demangled= my_demangle(begin, &status);
|
||||||
|
if (!demangled || status)
|
||||||
|
{
|
||||||
|
demangled= NULL;
|
||||||
|
begin[-1]= '(';
|
||||||
|
end[-1]= '+';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (demangled)
|
||||||
|
fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s\n", addrs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* BACKTRACE_DEMANGLE */
|
||||||
|
|
||||||
|
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
|
||||||
|
{
|
||||||
|
void *addrs[128];
|
||||||
|
char **strings= NULL;
|
||||||
|
int n = backtrace(addrs, array_elements(addrs));
|
||||||
|
#if BACKTRACE_DEMANGLE
|
||||||
|
if ((strings= backtrace_symbols(addrs, n)))
|
||||||
|
{
|
||||||
|
my_demangle_symbols(strings, n);
|
||||||
|
free(strings);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if HAVE_BACKTRACE_SYMBOLS_FD
|
||||||
|
if (!strings)
|
||||||
|
{
|
||||||
|
backtrace_symbols_fd(addrs, n, fileno(stderr));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(TARGET_OS_LINUX)
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
#define SIGRETURN_FRAME_OFFSET 17
|
#define SIGRETURN_FRAME_OFFSET 17
|
||||||
@ -108,74 +174,8 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
|
|||||||
}
|
}
|
||||||
#endif /* defined(__alpha__) && defined(__GNUC__) */
|
#endif /* defined(__alpha__) && defined(__GNUC__) */
|
||||||
|
|
||||||
#if BACKTRACE_DEMANGLE
|
|
||||||
|
|
||||||
char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void my_demangle_symbols(char **addrs, int n)
|
|
||||||
{
|
|
||||||
int status, i;
|
|
||||||
char *begin, *end, *demangled;
|
|
||||||
|
|
||||||
for (i= 0; i < n; i++)
|
|
||||||
{
|
|
||||||
demangled= NULL;
|
|
||||||
begin= strchr(addrs[i], '(');
|
|
||||||
end= begin ? strchr(begin, '+') : NULL;
|
|
||||||
|
|
||||||
if (begin && end)
|
|
||||||
{
|
|
||||||
*begin++= *end++= '\0';
|
|
||||||
demangled= my_demangle(begin, &status);
|
|
||||||
if (!demangled || status)
|
|
||||||
{
|
|
||||||
demangled= NULL;
|
|
||||||
begin[-1]= '(';
|
|
||||||
end[-1]= '+';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demangled)
|
|
||||||
fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s\n", addrs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_BACKTRACE
|
|
||||||
static void backtrace_current_thread(void)
|
|
||||||
{
|
|
||||||
void *addrs[128];
|
|
||||||
char **strings= NULL;
|
|
||||||
int n = backtrace(addrs, array_elements(addrs));
|
|
||||||
#if BACKTRACE_DEMANGLE
|
|
||||||
if ((strings= backtrace_symbols(addrs, n)))
|
|
||||||
{
|
|
||||||
my_demangle_symbols(strings, n);
|
|
||||||
free(strings);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if HAVE_BACKTRACE_SYMBOLS_FD
|
|
||||||
if (!strings)
|
|
||||||
{
|
|
||||||
backtrace_symbols_fd(addrs, n, fileno(stderr));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
|
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
|
||||||
{
|
{
|
||||||
#if HAVE_BACKTRACE
|
|
||||||
backtrace_current_thread();
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
uchar** fp;
|
uchar** fp;
|
||||||
uint frame_count = 0, sigreturn_frame_count;
|
uint frame_count = 0, sigreturn_frame_count;
|
||||||
#if defined(__alpha__) && defined(__GNUC__)
|
#if defined(__alpha__) && defined(__GNUC__)
|
||||||
|
@ -2538,7 +2538,9 @@ static void init_signals(void)
|
|||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
|
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_STACKTRACE
|
||||||
my_init_stacktrace();
|
my_init_stacktrace();
|
||||||
|
#endif
|
||||||
#if defined(__amiga__)
|
#if defined(__amiga__)
|
||||||
sa.sa_handler=(void(*)())handle_segfault;
|
sa.sa_handler=(void(*)())handle_segfault;
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user