summaryrefslogtreecommitdiff
path: root/mysys/my_addr_resolve.c
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-10-25 15:47:53 +0200
committerSergei Golubchik <serg@mariadb.org>2016-12-12 20:27:20 +0100
commite336fc07bdd4e81b7bf085e323610d7e251d542c (patch)
tree42448f559b4d7616fdea1ea9e563e4d1335aa75e /mysys/my_addr_resolve.c
parent855f0b9b16c22b439743ee06ead97421622b4c00 (diff)
downloadmariadb-git-e336fc07bdd4e81b7bf085e323610d7e251d542c.tar.gz
fix stack traces when linking with libbfd
also, return different values for different errors in my_addr_resolve()
Diffstat (limited to 'mysys/my_addr_resolve.c')
-rw-r--r--mysys/my_addr_resolve.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 72b04119855..83716bf11e1 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -34,6 +34,13 @@ static const char *strip_path(const char *s)
return prev;
}
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+#include <link.h>
+static ptrdiff_t offset= 0;
+#else
+#define offset 0
+#endif
+
/*
The following is very much single-threaded code and it's only supposed
to be used on shutdown or for a crash report
@@ -60,7 +67,7 @@ static asymbol **symtable= 0;
*/
int my_addr_resolve(void *ptr, my_addr_loc *loc)
{
- bfd_vma addr= (intptr)ptr;
+ bfd_vma addr= (intptr)ptr - offset;
asection *sec;
for (sec= bfdh->sections; sec; sec= sec->next)
@@ -103,6 +110,12 @@ const char *my_addr_resolve_init()
uint unused;
char **matching;
+#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
+
bfdh= bfd_openr(my_progname, NULL);
if (!bfdh)
goto err;
@@ -133,13 +146,6 @@ err:
#include <m_string.h>
#include <ctype.h>
-#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
-#include <link.h>
-static ptrdiff_t offset= 0;
-#else
-#define offset 0
-#endif
-
static int in[2], out[2];
static int initialized= 0;
static char output[1024];
@@ -174,7 +180,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
extra_bytes_read= read(out[0], output + total_bytes_read,
sizeof(output) - total_bytes_read);
if (extra_bytes_read < 0)
- return 1;
+ return 2;
/* Timeout or max bytes read. */
if (extra_bytes_read == 0)
break;
@@ -184,7 +190,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
/* Failed starting addr2line. */
if (total_bytes_read == 0)
- return 1;
+ return 3;
/* Go through the addr2line response and get the required data.
The response is structured in 2 lines. The first line contains the function
@@ -205,14 +211,14 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
}
/* Response is malformed. */
if (filename_start == -1 || line_number_start == -1)
- return 1;
+ return 4;
loc->func= output;
loc->file= output + filename_start;
/* Addr2line was unable to extract any meaningful information. */
if (strcmp(loc->file, "??") == 0)
- return 1;
+ return 5;
loc->file= strip_path(loc->file);