← Back to team overview

maria-developers team mailing list archive

Re: 0c37211c2a2: Fixed my_addr_resolve

 

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@xxxxxxxxx>
> > > committer: Michael Widenius <michael.widenius@xxxxxxxxx>
> > > 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@xxxxxxxxxxx


References