summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-06-14 12:45:25 -0700
committerRoland McGrath <roland@redhat.com>2010-06-14 12:52:09 -0700
commitb9e851815475d70d86ff0eda21d07239dd042107 (patch)
tree30dbf308fd67cb0ec91c06637fa314356dc7e476
parentaa32f9237f6ce0c25cbe53291467c305b6481abb (diff)
downloadelfutils-b9e851815475d70d86ff0eda21d07239dd042107.tar.gz
libdwfl: Ignore debuginfo-path hits that find the main file again.
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/find-debuginfo.c26
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)
{