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
This commit is contained in:
Philippe Waroquiers 2020-03-01 22:43:31 +01:00
parent 3a2711c659
commit db07db4c87

View 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