diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-03-13 13:34:24 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-03-13 13:34:24 +0100 |
commit | 00f2e3139f8760056a8526245524c952cc0dfb98 (patch) | |
tree | 0a9cad942961ddfed56b1eb240b60ebb95b9573e | |
parent | 1cbc3790d37cab5a2309b055e35945099b48d4c2 (diff) | |
download | mariadb-git-00f2e3139f8760056a8526245524c952cc0dfb98.tar.gz |
alternative method of resolving addresses for safemalloc and crash handler.
don't link with libbfd, exec addr2line, if it's available at run time
-rw-r--r-- | include/my_stacktrace.h | 6 | ||||
-rw-r--r-- | mysys/my_addr_resolve.c | 66 |
2 files changed, 71 insertions, 1 deletions
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h index 65e2fc9b814..ebc30ed8b59 100644 --- a/include/my_stacktrace.h +++ b/include/my_stacktrace.h @@ -56,7 +56,11 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep); #endif #endif -#ifdef HAVE_BFD_H +#ifndef _WIN32 +#define MY_ADDR_RESOLVE_FORK +#endif + +#if defined(HAVE_BFD_H) || defined(MY_ADDR_RESOLVE_FORK) #define HAVE_MY_ADDR_RESOLVE 1 #endif diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 514f825750a..14f482d2c9c 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -129,4 +129,70 @@ err: yet another - just execute addr2line or eu-addr2line, whatever available, pipe the addresses to it, and parse the output */ + +#include <m_string.h> +#include <ctype.h> +static int in[2], out[2]; +static int initialized= 0; +int my_addr_resolve(void *ptr, my_addr_loc *loc) +{ + char input[32], *s; + char output[1024]; + size_t len; + + len= my_safe_snprintf(input, sizeof(input), "0x%p\n", ptr); + if (write(in[1], input, len) <= 0) + return 1; + if (read(out[0], output, sizeof(output)) <= 0) + return 1; + loc->func= s= output; + while (*s != '\n') + s++; + *s++= 0; + loc->file= s; + while (*s != ':') + s++; + *s++= 0; + loc->line= 0; + while (isdigit(*s)) + loc->line = loc->line * 10 + (*s++ - '0'); + *s = 0; + loc->file= strip_path(loc->file); + + return 0; +} + +const char *my_addr_resolve_init() +{ + if (!initialized) + { + pid_t pid; + + if (pipe(in) < 0) + return "pipe(in)"; + if (pipe(out) < 0) + return "pipe(out)"; + + pid = fork(); + if (pid == -1) + return "fork"; + + if (!pid) /* child */ + { + dup2(in[0], 0); + dup2(out[1], 1); + close(in[0]); + close(in[1]); + close(out[0]); + close(out[1]); + execlp("addr2line", "addr2line", "-C", "-f", "-e", my_progname, NULL); + exit(1); + } + + close(in[0]); + close(out[1]); + initialized= 1; + } + return 0; +} #endif |