]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Fix finding split debug info files not located by the build-id mechanism
authorDodji Seketeli <dodji@seketeli.org>
Thu, 13 Aug 2015 13:59:41 +0000 (15:59 +0200)
committerMark Wielaard <mjw@redhat.com>
Fri, 14 Aug 2015 14:44:42 +0000 (16:44 +0200)
[This bug has been found by using elfutils in the context of
 libabigail.  The initial bug report is
 https://sourceware.org/bugzilla/show_bug.cgi?id=18792.  The
 interesting comments start at is
 https://sourceware.org/bugzilla/show_bug.cgi?id=18792#c4]

suppose we have a debug info file that is located at a
/prefix1/usr/lib/debug/prefix2/libfoo.so.  Suppose also that the debug
info describes a binary that is located at /prefix1/prefix2/libfoo.so

Suppose the debug_link property inside the binary
/prefix1/prefix2/libfoo.so correctly contains the string "libfoo.so"
that designates the name of the debug info file.

The problem is, when find_debuginfo_in_path() is called with its
file_name parameter set to "/prefix1/prefix2/libfoo.so" and
mod->dwfl->callbacks->debuginfo_path set to
"/prefix1/lib/debug/", it fails to locate the debug
info file libfoo.so under "/prefix1/usr/lib/debug/prefix2/".

This patch fixes the issue by making find_debuginfo_in_path() try all
the sub-strings of "/prefix1/prefix2/libfoo.so "under"
"/prefix1/usr/lib/debug/", to find libfoo.so.  That is, it tries, in
order:
 - /prefix1/usr/lib/debug/prefix1/prefix2/libfoo.so
 - /prefix1/usr/lib/debug/prefix2/libfoo.so <-- and boom, it finds it!

Note that the patch tries the variations between the two candidates
above too.

The patch uses a goto.  I dislike gotos like anyone else, but then
here, not using this would imply a bigger change of the logic of that
function.  So I am proposing the scheme based on the goto instead.

* libdwfl/find-debuginfo.c (find_debuginfo_in_path): Try to locate
the debug info file named debuglink_file under
mod->dwfl->callbacks->debuginfo_path, by looking at the set of
sub-trees under mod->dwfl->callbacks->debuginfo_path which is
common to the set of non-absolute parent trees of file_name.

https://bugzilla.redhat.com/show_bug.cgi?id=1253367

Signed-off-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdwfl/ChangeLog
libdwfl/find-debuginfo.c
libdwfl/libdwfl.h

index 5059be6d24d699dad03c8a25c02b8298468140ff..3e36aa757dc0f9dbed31723ec3c3ce89a1510e9e 100644 (file)
@@ -1,3 +1,12 @@
+2015-08-14  Dodji Seketeli  <dodji@seketeli.org>
+
+       * find-debuginfo.c (find_debuginfo_in_path): Try to locate the
+       debug info file named debuglink_file under
+       mod->dwfl->callbacks->debuginfo_path, by looking at
+       the set of sub-trees under mod->dwfl->callbacks->debuginfo_path
+       which is common to the set of non-absolute parent trees of
+       file_name.
+
 2015-06-18  Mark Wielaard  <mjw@redhat.com>
 
        * find-debuginfo.c (try_open): Free fname on all failure paths.
index 1faa494d841ee76e305a2f7a44d11bba92a20921..6b8d1ac4b992f83177b2b980ac395bf21e30862e 100644 (file)
@@ -252,7 +252,15 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
          dir = p;
          if (mod->dw == NULL)
            {
-             subdir = file_dirname + 1;
+             subdir = file_dirname;
+             /* We want to explore all sub-subdirs.  Chop off one slash
+                at a time.  */
+           explore_dir:
+             subdir = strchr (subdir, '/');
+             if (subdir != NULL)
+               subdir = subdir + 1;
+             if (subdir && *subdir == 0)
+               continue;
              file = debuglink_file;
            }
          else
@@ -292,6 +300,9 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
                  }
                break;
              }
+           /* If possible try again with a sub-subdir.  */
+           if (mod->dw == NULL && subdir)
+             goto explore_dir;
            continue;
          default:
            goto fail_free;
index 2bb4f455af17dc05c125718123eb7655cbfe10b4..1098c833e6f23d0ea0233317aeac320b1f6e3852 100644 (file)
@@ -275,12 +275,14 @@ extern int dwfl_module_build_id (Dwfl_Module *mod,
    In searches for debuginfo by name, if the remainder of the
    element is empty, the directory containing the main file is
    tried; if it's an absolute path name, the absolute directory path
-   containing the main file is taken as a subdirectory of this path;
-   a relative path name is taken as a subdirectory of the directory
-   containing the main file.  Hence for /bin/ls, the default string
-   ":.debug:/usr/lib/debug" says to look in /bin, then /bin/.debug,
-   then /usr/lib/debug/bin, for the file name in the .gnu_debuglink
-   section (or "ls.debug" if none was found).  */
+   (and any subdirectory of that path) containing the main file is
+   taken as a subdirectory of this path; a relative path name is taken
+   as a subdirectory of the directory containing the main file.
+   Hence for /usr/bin/ls, the default string ":.debug:/usr/lib/debug"
+   says to look in /usr/bin, then /usr/bin/.debug, then the path subdirs
+   under /usr/lib/debug, in the order /usr/lib/debug/usr/bin, then
+   /usr/lib/debug/bin, and finally /usr/lib/debug, for the file name in
+   the .gnu_debuglink section (or "ls.debug" if none was found).  */
 
 /* Standard find_elf callback function working solely on build ID.
    This can be tried first by any find_elf callback, to use the