From: Roland McGrath Date: Mon, 14 Jun 2010 19:45:25 +0000 (-0700) Subject: libdwfl: Ignore debuginfo-path hits that find the main file again. X-Git-Tag: elfutils-0.148~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9e851815475d70d86ff0eda21d07239dd042107;p=thirdparty%2Felfutils.git libdwfl: Ignore debuginfo-path hits that find the main file again. --- diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 347ebcf4f..d9b216d5d 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,10 @@ +2010-06-14 Roland McGrath + + * find-debuginfo.c (try_open): Take new arg MAIN_STAT. Compare + candidate file to that st_dev/st_ino and pretend it didn't exist + if they match. + (find_debuginfo_in_path): Update caller, pass main file's info. + 2010-05-20 Roland McGrath * linux-proc-maps.c (find_sysinfo_ehdr): Renamed to ... diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c index 8fdaeb397..375bbaa8a 100644 --- a/libdwfl/find-debuginfo.c +++ b/libdwfl/find-debuginfo.c @@ -51,13 +51,15 @@ #include #include #include +#include #include "system.h" /* Try to open64 [DIR/][SUBDIR/]DEBUGLINK, return file descriptor or -1. On success, *DEBUGINFO_FILE_NAME has the malloc'd name of the open file. */ static int -try_open (const char *dir, const char *subdir, const char *debuglink, +try_open (const struct stat64 *main_stat, + const char *dir, const char *subdir, const char *debuglink, char **debuginfo_file_name) { char *fname; @@ -72,9 +74,19 @@ try_open (const char *dir, const char *subdir, const char *debuglink, : asprintf (&fname, "%s/%s/%s", dir, subdir, debuglink)) < 0) return -1; + struct stat64 st; int fd = TEMP_FAILURE_RETRY (open64 (fname, O_RDONLY)); if (fd < 0) free (fname); + else if (fstat64 (fd, &st) == 0 + && st.st_ino == main_stat->st_ino + && st.st_dev == main_stat->st_dev) + { + /* This is the main file by another name. Don't look at it again. */ + close (fd); + errno = ENOENT; + fd = -1; + } else *debuginfo_file_name = fname; @@ -162,6 +174,16 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, ++path; } + /* XXX dev/ino should be cached in struct dwfl_file. */ + struct stat64 main_stat; + if (unlikely ((mod->main.fd != -1 ? fstat64 (mod->main.fd, &main_stat) + : file_name != NULL ? stat64 (file_name, &main_stat) + : -1) < 0)) + { + main_stat.st_dev = 0; + main_stat.st_ino = 0; + } + char *file_dirname = (file_basename == file_name ? NULL : strndupa (file_name, file_basename - 1 - file_name)); char *p; @@ -199,7 +221,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, } char *fname = NULL; - int fd = try_open (dir, subdir, debuglink_file, &fname); + int fd = try_open (&main_stat, dir, subdir, debuglink_file, &fname); if (fd < 0) switch (errno) {