diff options
author | Roland McGrath <roland@redhat.com> | 2010-06-14 12:45:25 -0700 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2010-06-14 12:52:09 -0700 |
commit | b9e851815475d70d86ff0eda21d07239dd042107 (patch) | |
tree | 30dbf308fd67cb0ec91c06637fa314356dc7e476 | |
parent | aa32f9237f6ce0c25cbe53291467c305b6481abb (diff) | |
download | elfutils-b9e851815475d70d86ff0eda21d07239dd042107.tar.gz |
libdwfl: Ignore debuginfo-path hits that find the main file again.
-rw-r--r-- | libdwfl/ChangeLog | 7 | ||||
-rw-r--r-- | libdwfl/find-debuginfo.c | 26 |
2 files changed, 31 insertions, 2 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 347ebcf4..d9b216d5 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,10 @@ +2010-06-14 Roland McGrath <roland@redhat.com> + + * 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 <roland@redhat.com> * linux-proc-maps.c (find_sysinfo_ehdr): Renamed to ... diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c index 8fdaeb39..375bbaa8 100644 --- a/libdwfl/find-debuginfo.c +++ b/libdwfl/find-debuginfo.c @@ -51,13 +51,15 @@ #include <stdio.h> #include <fcntl.h> #include <unistd.h> +#include <sys/stat.h> #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) { |