mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
Bug#31891 Meaningful stack trace
On crashes generate a user-friendly resolved and demangled stack trace when libc provides the necessary functions (newer libc on i386, x86_64, powerpc, ia64, alpha and s390). Otherwise print a numeric stack trace as before, relying on resolve_stack_dump utility.
This commit is contained in:
21
configure.in
21
configure.in
@@ -813,8 +813,8 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
|
|||||||
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
|
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
|
||||||
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
|
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
|
||||||
sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \
|
sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \
|
||||||
sys/prctl.h \
|
sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \
|
||||||
sys/resource.h sys/param.h port.h ieeefp.h)
|
execinfo.h)
|
||||||
|
|
||||||
AC_CHECK_HEADERS([xfs/xfs.h])
|
AC_CHECK_HEADERS([xfs/xfs.h])
|
||||||
|
|
||||||
@@ -2041,7 +2041,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
|
|||||||
sighold sigset sigthreadmask port_create sleep \
|
sighold sigset sigthreadmask port_create sleep \
|
||||||
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
|
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
|
||||||
strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
|
strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
|
||||||
posix_fallocate)
|
posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -2331,6 +2331,21 @@ then
|
|||||||
fi
|
fi
|
||||||
AC_MSG_RESULT("$netinet_inc")
|
AC_MSG_RESULT("$netinet_inc")
|
||||||
|
|
||||||
|
AC_LANG_SAVE
|
||||||
|
AC_LANG_CPLUSPLUS
|
||||||
|
AC_CHECK_HEADERS(cxxabi.h)
|
||||||
|
AC_CACHE_CHECK([checking for abi::__cxa_demangle], mysql_cv_cxa_demangle,
|
||||||
|
[AC_TRY_LINK([#include <cxxabi.h>], [
|
||||||
|
char *foo= 0; int bar= 0;
|
||||||
|
foo= abi::__cxa_demangle(foo, foo, 0, &bar);
|
||||||
|
], [mysql_cv_cxa_demangle=yes], [mysql_cv_cxa_demangle=no])])
|
||||||
|
AC_LANG_RESTORE
|
||||||
|
|
||||||
|
if test "x$mysql_cv_cxa_demangle" = xyes; then
|
||||||
|
AC_DEFINE(HAVE_ABI_CXA_DEMANGLE, 1,
|
||||||
|
[Define to 1 if you have the `abi::__cxa_demangle' function.])
|
||||||
|
fi
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Check for requested features
|
# Check for requested features
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
@@ -2182,6 +2182,16 @@ static void check_data_home(const char *path)
|
|||||||
#define UNSAFE_DEFAULT_LINUX_THREADS 200
|
#define UNSAFE_DEFAULT_LINUX_THREADS 200
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if BACKTRACE_DEMANGLE
|
||||||
|
#include <cxxabi.h>
|
||||||
|
extern "C" char *my_demangle(const char *mangled_name, int *status)
|
||||||
|
{
|
||||||
|
return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C" sig_handler handle_segfault(int sig)
|
extern "C" sig_handler handle_segfault(int sig)
|
||||||
{
|
{
|
||||||
time_t curr_time;
|
time_t curr_time;
|
||||||
@@ -2253,10 +2263,29 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
|
|||||||
}
|
}
|
||||||
if (thd)
|
if (thd)
|
||||||
{
|
{
|
||||||
|
const char *kreason= "UNKNOWN";
|
||||||
|
switch (thd->killed) {
|
||||||
|
case THD::NOT_KILLED:
|
||||||
|
kreason= "NOT_KILLED";
|
||||||
|
break;
|
||||||
|
case THD::KILL_BAD_DATA:
|
||||||
|
kreason= "KILL_BAD_DATA";
|
||||||
|
break;
|
||||||
|
case THD::KILL_CONNECTION:
|
||||||
|
kreason= "KILL_CONNECTION";
|
||||||
|
break;
|
||||||
|
case THD::KILL_QUERY:
|
||||||
|
kreason= "KILL_QUERY";
|
||||||
|
break;
|
||||||
|
case THD::KILLED_NO_VALUE:
|
||||||
|
kreason= "KILLED_NO_VALUE";
|
||||||
|
break;
|
||||||
|
}
|
||||||
fprintf(stderr, "Trying to get some variables.\n\
|
fprintf(stderr, "Trying to get some variables.\n\
|
||||||
Some pointers may be invalid and cause the dump to abort...\n");
|
Some pointers may be invalid and cause the dump to abort...\n");
|
||||||
safe_print_str("thd->query", thd->query, 1024);
|
safe_print_str("thd->query", thd->query, 1024);
|
||||||
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
|
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
|
||||||
|
fprintf(stderr, "thd->killed=%s\n", kreason);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\
|
fprintf(stderr, "\
|
||||||
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
|
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
|
||||||
|
@@ -17,11 +17,16 @@
|
|||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <my_pthread.h>
|
#include <my_pthread.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
#ifdef HAVE_STACKTRACE
|
#ifdef HAVE_STACKTRACE
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
|
#if HAVE_EXECINFO_H
|
||||||
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#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)
|
||||||
|
|
||||||
char *heap_start;
|
char *heap_start;
|
||||||
@@ -93,9 +98,68 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
|
|||||||
}
|
}
|
||||||
#endif /* defined(__alpha__) && defined(__GNUC__) */
|
#endif /* defined(__alpha__) && defined(__GNUC__) */
|
||||||
|
|
||||||
|
#if BACKTRACE_DEMANGLE
|
||||||
|
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 print_stacktrace(uchar* stack_bottom, ulong thread_stack)
|
void 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__)
|
||||||
|
@@ -17,6 +17,14 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE
|
||||||
|
#define BACKTRACE_DEMANGLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BACKTRACE_DEMANGLE
|
||||||
|
char *my_demangle(const char *mangled_name, int *status);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TARGET_OS_LINUX
|
#ifdef TARGET_OS_LINUX
|
||||||
#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
|
#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
|
||||||
#undef HAVE_STACKTRACE
|
#undef HAVE_STACKTRACE
|
||||||
|
Reference in New Issue
Block a user