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 #include + +#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN) +#include +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)