summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-03-13 13:34:24 +0100
committerSergei Golubchik <sergii@pisem.net>2012-03-13 13:34:24 +0100
commit00f2e3139f8760056a8526245524c952cc0dfb98 (patch)
tree0a9cad942961ddfed56b1eb240b60ebb95b9573e
parent1cbc3790d37cab5a2309b055e35945099b48d4c2 (diff)
downloadmariadb-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.h6
-rw-r--r--mysys/my_addr_resolve.c66
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