summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-02-28 13:51:22 +0100
committerSergei Golubchik <serg@mariadb.org>2015-02-28 19:48:22 +0100
commitc78f594bbc934a080c5008ddc7a11daf2595a75c (patch)
tree129e723a8be3f782f16b02fad6c939851602faff
parent7ba2916c552638e3f8ab4cf2945bbfe99f745dd4 (diff)
downloadmariadb-git-c78f594bbc934a080c5008ddc7a11daf2595a75c.tar.gz
MDEV-6479 stack traces in 10.1
Take into account that PIE binaries are loaded at some offset, so addresses cannot be directly resolved with addr2line. Find this offset and subtract it before resolving an address.
-rw-r--r--config.h.cmake1
-rw-r--r--configure.cmake1
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--mysys/my_addr_resolve.c20
4 files changed, 20 insertions, 4 deletions
diff --git a/config.h.cmake b/config.h.cmake
index bd3f4a9ebd6..7964bf30ded 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -46,6 +46,7 @@
#cmakedefine HAVE_INTTYPES_H 1
#cmakedefine HAVE_KQUEUE 1
#cmakedefine HAVE_LIMITS_H 1
+#cmakedefine HAVE_LINK_H 1
#cmakedefine HAVE_LINUX_UNISTD_H 1
#cmakedefine HAVE_LOCALE_H 1
#cmakedefine HAVE_MALLOC_H 1
diff --git a/configure.cmake b/configure.cmake
index 8c966a33a77..22a5d59bfb1 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -188,6 +188,7 @@ CHECK_INCLUDE_FILES (grp.h HAVE_GRP_H)
CHECK_INCLUDE_FILES (ieeefp.h HAVE_IEEEFP_H)
CHECK_INCLUDE_FILES (inttypes.h HAVE_INTTYPES_H)
CHECK_INCLUDE_FILES (langinfo.h HAVE_LANGINFO_H)
+CHECK_INCLUDE_FILES (link.h HAVE_LINK_H)
CHECK_INCLUDE_FILES (linux/unistd.h HAVE_LINUX_UNISTD_H)
CHECK_INCLUDE_FILES (linux/falloc.h HAVE_LINUX_FALLOC_H)
CHECK_INCLUDE_FILES (limits.h HAVE_LIMITS_H)
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 0fd3eb12657..0d404586569 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -71,7 +71,7 @@ ENDIF()
ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES})
TARGET_LINK_LIBRARIES(mysys dbug strings mysys_ssl ${ZLIB_LIBRARY}
- ${LIBNSL} ${LIBM} ${LIBRT} ${LIBSOCKET} ${LIBEXECINFO})
+ ${LIBNSL} ${LIBM} ${LIBRT} ${LIBDL} ${LIBSOCKET} ${LIBEXECINFO})
DTRACE_INSTRUMENT(mysys)
IF(HAVE_BFD_H)
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 90e6f43f390..1509487651d 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -126,12 +126,20 @@ err:
*/
#elif defined(MY_ADDR_RESOLVE_FORK)
/*
- yet another - just execute addr2line or eu-addr2line, whatever available,
- pipe the addresses to it, and parse the output
+ yet another - just execute addr2line pipe the addresses to it, and parse the
+ output
*/
#include <m_string.h>
#include <ctype.h>
+
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+#include <link.h>
+static ElfW(Addr) offset= 0;
+#else
+#define offset 0
+#endif
+
static int in[2], out[2];
static int initialized= 0;
static char output[1024];
@@ -140,7 +148,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
char input[32], *s;
size_t len;
- len= my_snprintf(input, sizeof(input), "%p\n", ptr);
+ len= my_snprintf(input, sizeof(input), "%p\n", ptr - offset);
if (write(in[1], input, len) <= 0)
return 1;
if (read(out[0], output, sizeof(output)) <= 0)
@@ -172,6 +180,12 @@ const char *my_addr_resolve_init()
{
pid_t pid;
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+ struct link_map *lm = (struct link_map*) dlopen(0, RTLD_NOW);
+ if (lm)
+ offset= lm->l_addr;
+#endif
+
if (pipe(in) < 0)
return "pipe(in)";
if (pipe(out) < 0)