Re: [Maria-developers] 0c37211c2a2: Fixed my_addr_resolve
Hi, Michael! On Mar 28, Michael Widenius wrote:
revision-id: 0c37211c2a2 (mariadb-10.5.2-517-g0c37211c2a2) parent(s): 555c4470130 author: Michael Widenius <michael.widenius@gmail.com> committer: Michael Widenius <michael.widenius@gmail.com> timestamp: 2021-03-24 14:31:53 +0200 message:
Fixed my_addr_resolve
At least on openSUSE Leap 15.1 one should not use the dli_fbase offset provided by dladdr() for addresses in the main program. Without this patch the stack traces from sf_report_leaked_memory() are not usable.
This is very strange. First, the whole purpose of this code is to use dli_fbase offset for the main program. That's why it was added in the first place. PIE binaries can be loaded at any address in memory and the address you see with addr2line or nm or readelf is not the same address you'll see in gdb or in a strack trace. We have to subtract the base address first. But may be openSUSE is different? So, I built on openSUSE Leap and the stack trace was perfectly usable without your patch. I tried both `kill -ABRT` and an artificially introduced memory leak. So I suspect there was some misunderstanding and the problem was somewhere else (I cannot know what, of course, but just as an example - the build was bad and recompilation fixed it). Regards, Sergei VP of MariaDB Server Engineering and security@mariadb.org
Hi! On Sun, Mar 28, 2021 at 2:54 PM Sergei Golubchik <serg@mariadb.org> wrote:
Hi, Michael!
On Mar 28, Michael Widenius wrote:
revision-id: 0c37211c2a2 (mariadb-10.5.2-517-g0c37211c2a2) parent(s): 555c4470130 author: Michael Widenius <michael.widenius@gmail.com> committer: Michael Widenius <michael.widenius@gmail.com> timestamp: 2021-03-24 14:31:53 +0200 message:
Fixed my_addr_resolve
At least on openSUSE Leap 15.1 one should not use the dli_fbase offset provided by dladdr() for addresses in the main program. Without this patch the stack traces from sf_report_leaked_memory() are not usable.
This is very strange. First, the whole purpose of this code is to use dli_fbase offset for the main program. That's why it was added in the first place. PIE binaries can be loaded at any address in memory and the address you see with addr2line or nm or readelf is not the same address you'll see in gdb or in a strack trace. We have to subtract the base address first.
But may be openSUSE is different? So, I built on openSUSE Leap and the stack trace was perfectly usable without your patch. I tried both `kill -ABRT` and an artificially introduced memory leak.
So I suspect there was some misunderstanding and the problem was somewhere else (I cannot know what, of course, but just as an example - the build was bad and recompilation fixed it).
This was checked extensively by both me and Vicentiu (both looking at the assembler and the examining the output). Without the patch I get constantly wrong stack traces for the main program. We also tried to find exactly how dli_fbase exactly should be used on the internet, but could not find any good documentation for it. The simple fact is that I am using this patch on my 10.6 tree and stack traces are good with it and has been for several months, so it is impossible that this is related to a bad binary or bad build but something that is required on my system Regards, Monty
Hi, Michael! On Mar 28, Michael Widenius wrote:
On Mar 28, Michael Widenius wrote:
revision-id: 0c37211c2a2 (mariadb-10.5.2-517-g0c37211c2a2) parent(s): 555c4470130 author: Michael Widenius <michael.widenius@gmail.com> committer: Michael Widenius <michael.widenius@gmail.com> timestamp: 2021-03-24 14:31:53 +0200 message:
Fixed my_addr_resolve
At least on openSUSE Leap 15.1 one should not use the dli_fbase offset provided by dladdr() for addresses in the main program. Without this patch the stack traces from sf_report_leaked_memory() are not usable.
You build non-PIE binaries, in that case subtracting dli_fbase offset is not needed. Normally we always build and ship PIE binaries, and then subtracting dli_fbase is required, without it stack frames won't resolve. I don't know how to detect PIE during compilation (__PIE__ doesn't work reliably enough, e.g. on your gcc 7.5), so here's a patch that does it at runtime, though I feel rather silly detecting compilation options at runtime. ========== --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -170,6 +170,7 @@ static pid_t pid; static char addr2line_binary[1024]; static char output[1024]; static struct pollfd poll_fds; +static void *offset; int start_addr2line_fork(const char *binary_path) { @@ -297,8 +298,6 @@ static int addr_resolve(void *ptr, my_addr_loc *loc) int my_addr_resolve(void *ptr, my_addr_loc *loc) { Dl_info info; - int error; - void *offset; if (!dladdr(ptr, &info)) return 1; @@ -319,16 +318,14 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) } /* Save result for future comparisons. */ strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary)); + offset= info.dli_fbase; + if (strcmp(info.dli_fname, my_progname) == 0 && + addr_resolve((void*) my_addr_resolve, loc) == 0 && + strcmp(loc->func, "my_addr_resolve") == 0) + offset= 0; } - offset= info.dli_fbase; - /* offset is 0 for the current executable (not shared library */ - if (strcmp(info.dli_fname, my_progname) == 0) - offset= 0; - - if (!(error= addr_resolve((void*) (ptr - offset), loc))) - return 0; - return error; + return addr_resolve((void*) (ptr - offset), loc); } ========== Regards, Sergei VP of MariaDB Server Engineering and security@mariadb.org
participants (2)
-
Michael Widenius
-
Sergei Golubchik