summaryrefslogtreecommitdiff
path: root/sql/stacktrace.c
diff options
context:
space:
mode:
authorunknown <davi@mysql.com/endora.local>2008-02-07 19:58:06 -0200
committerunknown <davi@mysql.com/endora.local>2008-02-07 19:58:06 -0200
commitd9831ae5329d6916667ee9beb885c3e4c35c4018 (patch)
tree8ec03724213bdbbf26572c207c4b29a76055757f /sql/stacktrace.c
parentee0b7f38567bf8661d89500b67d115d8a1cb53f8 (diff)
downloadmariadb-git-d9831ae5329d6916667ee9beb885c3e4c35c4018.tar.gz
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. configure.in: Add check for backtrace headers, backtrace functions and if __cxa_demangle (libstdc++) is available at link time. sql/mysqld.cc: Print the value of the THD::killed variable when dumping. In some circumstances knowing if the thread was killed makes debugging easier. sql/stacktrace.c: Use the glibc backtrace function when available and demangle C++ function names if the __cxa_demangle function is available. sql/stacktrace.h: Locally export and wrap in C linkage the C++ function __cxa_demangle if available.
Diffstat (limited to 'sql/stacktrace.c')
-rw-r--r--sql/stacktrace.c64
1 files changed, 64 insertions, 0 deletions
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__)