]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Allow valgrind to find debug info in a 'usr merge' setup.
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sun, 1 Mar 2020 21:43:31 +0000 (22:43 +0100)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sun, 1 Mar 2020 21:43:31 +0000 (22:43 +0100)
On ubuntu 19.10, valgrind fails telling that it cannot find
the mandatory redirection for strlen in ld-linux-x86-64.so.2.

This is due to /bin being a symlink to usr/bin: ld is found
in /usr/lib/x86_64-linux-gnu/ld-2.30.so
but its debug info is
in /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.30.so

Without this patch, valgrind searches the debug info (a.o.)
in /usr/lib/debug/usr/lib/x86_64-linux-gnu/ld-2.30.so
so using the concatenation of  /usr/lib/debug
and /usr/lib/x86_64-linux-gnu/ld-2.30.so,
but the debug info is located at the concatenation of
/usr/lib/debug and /lib/x86_64-linux-gnu/ld-2.30.so
(so without the leading /usr).
Modify the debug info search so as to try with and without the /usr.

Patch derived from the patch done by Mathieu Trudel-Lapierre
to solve https://bugs.launchpad.net/ubuntu/+source/valgrind/+bug/1808508

coregrind/m_debuginfo/readelf.c

index 40e546a8475fcc9a79a3b1ef5f0abd2968cae561..bc5a732d7b0a0e2fb6a0809ea06e7a3ee6b5a1d7 100644 (file)
@@ -1316,41 +1316,53 @@ DiImage* find_debug_file( struct _DebugInfo* di,
 
    if (dimg == NULL && debugname != NULL) {
       HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
+      HChar *usrmerge_objdir;
       HChar *objdirptr;
 
       if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
          *objdirptr = '\0';
 
+      if ((objdirptr = VG_(strstr)(objdir, "usr")) != NULL)
+         usrmerge_objdir = objdirptr + VG_(strlen)("usr");
+      else
+         usrmerge_objdir = NULL;
+
       debugpath = ML_(dinfo_zalloc)(
                      "di.fdf.3",
                      VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
                      + (extrapath ? VG_(strlen)(extrapath) : 0)
                      + (serverpath ? VG_(strlen)(serverpath) : 0));
 
+#     define TRY_OBJDIR(format, ...)                                    \
+      do {                                                              \
+         VG_(sprintf)(debugpath, format, __VA_ARGS__);                  \
+         dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL); \
+         if (dimg != NULL) goto dimg_ok;                                \
+      } while (0);
+
+#     define TRY_OBJDIR_USRMERGE_OBJDIR(format)                         \
+      do {                                                              \
+         TRY_OBJDIR(format, objdir, debugname);                         \
+         if (usrmerge_objdir != NULL) {                                 \
+            TRY_OBJDIR(format, usrmerge_objdir, debugname);             \
+         }                                                              \
+      } while (0)
+
       if (debugname[0] == '/') {
-         VG_(sprintf)(debugpath, "%s", debugname);
-         dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
-         if (dimg != NULL) goto dimg_ok;
+         TRY_OBJDIR("%s", debugname);
       }
 
-      VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
-      dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
-      if (dimg != NULL) goto dimg_ok;
-
-      VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
-      dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
-      if (dimg != NULL) goto dimg_ok;
-      
-      VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
-      dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
-      if (dimg != NULL) goto dimg_ok;
+      TRY_OBJDIR_USRMERGE_OBJDIR("%s/%s");
+      TRY_OBJDIR_USRMERGE_OBJDIR("%s/.debug/%s");
+      TRY_OBJDIR_USRMERGE_OBJDIR("/usr/lib/debug%s/%s");
 
       if (extrapath) {
-         VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
-                                            objdir, debugname);
-         dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
-         if (dimg != NULL) goto dimg_ok;
+         TRY_OBJDIR("%s%s/%s", extrapath, objdir, debugname);
+         if (usrmerge_objdir != NULL)
+            TRY_OBJDIR("%s%s/%s", extrapath, usrmerge_objdir, debugname);
       }
+#     undef TRY_OBJDIR
+#     undef TRY_OBJDIRS
 
       if (serverpath) {
          /* When looking on the debuginfo server, always just pass the