From: Philippe Waroquiers Date: Sun, 1 Mar 2020 21:43:31 +0000 (+0100) Subject: Allow valgrind to find debug info in a 'usr merge' setup. X-Git-Tag: VALGRIND_3_16_0~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db07db4c8706d17124a621a254bee1b6f08d2e1d;p=thirdparty%2Fvalgrind.git Allow valgrind to find debug info in a 'usr merge' setup. 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 --- diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index 40e546a847..bc5a732d7b 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -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