diff options
Diffstat (limited to 'mysys/my_addr_resolve.c')
-rw-r--r-- | mysys/my_addr_resolve.c | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 7590d576a7c..ff15558ddd4 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -191,7 +191,9 @@ int start_addr2line_fork(const char *binary_path) return 0; } -int my_addr_resolve(void *ptr, my_addr_loc *loc) +static int first_error= 0; + +static int addr_resolve(void *ptr, my_addr_loc *loc) { char input[32]; size_t len; @@ -206,29 +208,13 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) int filename_start = -1; int line_number_start = -1; - Dl_info info; - void *offset; - - if (!dladdr(ptr, &info)) - return 1; - - if (strcmp(addr2line_binary, info.dli_fname)) - { - /* We use dli_fname in case the path is longer than the length of our static - string. We don't want to allocate anything dynamicaly here as we are in - a "crashed" state. */ - if (start_addr2line_fork(info.dli_fname)) - { - addr2line_binary[0] = '\0'; - return 2; - } - /* Save result for future comparisons. */ - strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary)); - } - offset = info.dli_fbase; - len= my_snprintf(input, sizeof(input), "%08x\n", (ulonglong)(ptr - offset)); + len= my_snprintf(input, sizeof(input), "%p\n", ptr); if (write(in[1], input, len) <= 0) + { + if (!first_error++) + fputs("Printing to addr2line failed\n", stderr); return 3; + } FD_ZERO(&set); FD_SET(out[0], &set); @@ -278,7 +264,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) loc->line= atoi(output + line_number_start); /* Addr2line was unable to extract any meaningful information. */ - if (strcmp(loc->file, "??") == 0) + if (strcmp(loc->file, "??") == 0 && loc->func[0] == '?') return 6; loc->file= strip_path(loc->file); @@ -286,6 +272,42 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) return 0; } + +int my_addr_resolve(void *ptr, my_addr_loc *loc) +{ + Dl_info info; + int error; + + if (!dladdr(ptr, &info)) + return 1; + + if (strcmp(addr2line_binary, info.dli_fname)) + { + /* + We use dli_fname in case the path is longer than the length of + our static string. We don't want to allocate anything + dynamicaly here as we are in a "crashed" state. + */ + if (start_addr2line_fork(info.dli_fname)) + { + if (!first_error++) + fputs("Can't start addr2line\n", stderr); + addr2line_binary[0] = '\0'; + return 2; + } + /* Save result for future comparisons. */ + strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary)); + } + if (!(error= addr_resolve(ptr, loc))) + return 0; +#ifdef EXTRA_RESOLVE + if (!(error= addr_resolve((void*) (ptr - info.dli_fbase), loc))) + return 0; +#endif + return error; +} + + const char *my_addr_resolve_init() { return 0; |