revision-id: 1cc0462d429707959b79fd1ae622d0c38ed9211d (mariadb-5.5.59-57-g1cc0462d429) parent(s): 3eb2a265eac53050089bc5d563e65161717a2983 author: Vicențiu Ciorbaru committer: Vicențiu Ciorbaru timestamp: 2018-04-09 20:44:11 +0300 message: Fix printing of line numbers when using addr2line When starting a binary that's inside the PATH variable without specifying a complete path, dladdr will return just that binary name, without any extra path information. Make use of /proc/self/exe if it's available to resolve it. --- mysys/my_addr_resolve.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 02f71fd72bd..1202e5040d8 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -184,18 +184,36 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) char input[32], *s; size_t len; + ssize_t bytes_written; Dl_info info; void *offset; + const char *binary_name; + if (!dladdr(ptr, &info)) return 1; if (strcmp(addr2line_binary, info.dli_fname)) { + /* Check if we have an absolute or relative path. If there's no sign of a + path in the dli_fname string, we are looking at a binary started using + a PATH variable lookup. This only happens for the base binary file. */ + binary_name= info.dli_fname; + if (!strchr(binary_name, '/')) + { + /* Temporarily reuse "output" array to store the full path. + If this call fails, we will just use info.dli_fname. */ + bytes_written= readlink("/proc/self/exe", output, sizeof(output) - 1); + if (bytes_written >= 0) + { + output[bytes_written] = '\0'; + binary_name= output; + } + } /* 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 (start_addr2line_fork(binary_name)) { addr2line_binary[0] = '\0'; return 1;