summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in21
-rw-r--r--sql/mysqld.cc29
-rw-r--r--sql/stacktrace.c64
-rw-r--r--sql/stacktrace.h8
4 files changed, 119 insertions, 3 deletions
diff --git a/configure.in b/configure.in
index 1346a87c35a..2e623aacaf7 100644
--- a/configure.in
+++ b/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 \
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/prctl.h \
- sys/resource.h sys/param.h port.h ieeefp.h)
+ sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \
+ execinfo.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 \
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
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
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
#--------------------------------------------------------------------
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 9dc77fb8356..84f7620962e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2182,6 +2182,16 @@ static void check_data_home(const char *path)
#define UNSAFE_DEFAULT_LINUX_THREADS 200
#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)
{
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)
{
+ 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\
Some pointers may be invalid and cause the dump to abort...\n");
safe_print_str("thd->query", thd->query, 1024);
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
+ fprintf(stderr, "thd->killed=%s\n", kreason);
}
fprintf(stderr, "\
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index b1267e20774..3d718dfd9d2 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -17,11 +17,16 @@
#include "stacktrace.h"
#include <signal.h>
#include <my_pthread.h>
+#include <m_string.h>
#ifdef HAVE_STACKTRACE
#include <unistd.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)
char *heap_start;
@@ -93,9 +98,68 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
}
#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)
{
+#if HAVE_BACKTRACE
+ backtrace_current_thread();
+ return;
+#endif
uchar** fp;
uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__)
diff --git a/sql/stacktrace.h b/sql/stacktrace.h
index 1a0b80c88d3..96c09a21ad6 100644
--- a/sql/stacktrace.h
+++ b/sql/stacktrace.h
@@ -17,6 +17,14 @@
extern "C" {
#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
#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE