From 8e96119159a946b1b56c1f8ea78f924e06c2cb88 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 24 Nov 2023 18:50:15 +0200 Subject: [PATCH] Backport my_addr_resolve from 10.6 to get latest bug fixes in. This will enable safemalloc to resolve symbols when compiled with __PIE__ --- mysys/my_addr_resolve.c | 82 ++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 52fcaaf67bb..376e73686e2 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -170,7 +170,7 @@ static pid_t pid; static char addr2line_binary[1024]; static char output[1024]; static struct pollfd poll_fds; -static Dl_info info; +static void *addr_offset; int start_addr2line_fork(const char *binary_path) { @@ -211,7 +211,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; @@ -225,31 +227,16 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) int filename_start = -1; int line_number_start = -1; - void *offset; - poll_fds.fd = out[0]; poll_fds.events = POLLIN | POLLRDBAND; - 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; + } /* 5000 ms should be plenty of time for addr2line to issue a response. */ @@ -308,6 +295,57 @@ 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; + + 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 + dynamically 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)); + +#ifdef _AIX + /* + info.dli_fbase is a char on AIX and casting it doesn't fool gcc. + leave backtracing broken on AIX until a real solution can be found. + */ + addr_offset= NULL; +#else + /* + Check if we should use info.dli_fbase as an offset or not + for the base program. This is depending on if the compilation is + done with PIE or not. + */ + addr_offset= info.dli_fbase; +#endif +#ifndef __PIE__ + if (strcmp(info.dli_fname, my_progname) == 0 && + addr_resolve((void*) my_addr_resolve, loc) == 0 && + strcmp(loc->func, "my_addr_resolve") == 0) + addr_offset= 0; +#endif + } + + return addr_resolve((void*) (ptr - addr_offset), loc); +} + + const char *my_addr_resolve_init() { return 0;