aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/NEWS11
-rw-r--r--gdb/doc/ChangeLog4
-rw-r--r--gdb/doc/gdb.texinfo27
-rw-r--r--gdb/dwarf2read.c9
-rw-r--r--gdb/psymtab.c9
-rw-r--r--gdb/symtab.c26
-rw-r--r--gdb/symtab.h2
8 files changed, 97 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2e866ba..98f7c7d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2011-11-15 Doug Evans <dje@google.com>
+
+ * NEWS: Mention new parameter basenames-may-differ.
+ * dwarf2read.c (dw2_lookup_symtab): Avoid calling gdb_realpath if
+ ! basenames_may_differ.
+ * psymtab.c (lookup_partial_symtab): Ditto.
+ * symtab.c (lookup_symtab): Ditto.
+ (basenames_may_differ): New global.
+ (_initialize_symtab): New parameter basenames-may-differ.
+ * symtab.h (basenames_may_differ): Declare.
+
2011-11-15 Pedro Alves <pedro@codesourcery.com>
Luis Machado <lgustavo@codesourcery.com>
diff --git a/gdb/NEWS b/gdb/NEWS
index bce8e3c..c4e59c4 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -165,6 +165,17 @@ show debug entry-values
Control display of debugging info for determining frame argument values at
function entry and virtual tail call frames.
+set basenames-may-differ
+show basenames-may-differ
+ Set whether a source file may have multiple base names.
+ (A "base name" is the name of a file with the directory part removed.
+ Example: The base name of "/home/user/hello.c" is "hello.c".)
+ If set, GDB will canonicalize file names (e.g., expand symlinks)
+ before comparing them. Canonicalization is an expensive operation,
+ but it allows the same file be known by more than one base name.
+ If not set (the default), all source files are assumed to have just
+ one base name, and gdb will do file name comparisons more efficiently.
+
* New remote packets
QTEnable
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 15659d6..4975cd2 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2011-11-15 Doug Evans <dje@google.com>
+
+ * gdb.texinfo (Files): Document basenames-may-differ.
+
2011-11-14 Doug Evans <dje@google.com>
* gdb.texinfo (Shell Commands): Document "!".
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 9255b89..f4f7f1e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -15705,6 +15705,33 @@ This is the default.
@end table
@end table
+@cindex file name canonicalization
+@cindex base name differences
+When processing file names provided by the user, @value{GDBN}
+frequently needs to compare them to the file names recorded in the
+program's debug info. Normally, @value{GDBN} compares just the
+@dfn{base names} of the files as strings, which is reasonably fast
+even for very large programs. (The base name of a file is the last
+portion of its name, after stripping all the leading directories.)
+This shortcut in comparison is based upon the assumption that files
+cannot have more than one base name. This is usually true, but
+references to files that use symlinks or similar filesystem
+facilities violate that assumption. If your program records files
+using such facilities, or if you provide file names to @value{GDBN}
+using symlinks etc., you can set @code{basenames-may-differ} to
+@code{true} to instruct @value{GDBN} to completely canonicalize each
+pair of file names it needs to compare. This will make file-name
+comparisons accurate, but at a price of a significant slowdown.
+
+@table @code
+@item set basenames-may-differ
+@kindex set basenames-may-differ
+Set whether a source file may have multiple base names.
+
+@item show basenames-may-differ
+@kindex show basenames-may-differ
+Show whether a source file may have multiple base names.
+@end table
@node Separate Debug Files
@section Debugging Information in Separate Files
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 5e5ee7c..5e279de 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -2445,7 +2445,8 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
struct symtab **result)
{
int i;
- int check_basename = lbasename (name) == name;
+ const char *name_basename = lbasename (name);
+ int check_basename = name_basename == name;
struct dwarf2_per_cu_data *base_cu = NULL;
dw2_setup (objfile);
@@ -2478,6 +2479,12 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
&& FILENAME_CMP (lbasename (this_name), name) == 0)
base_cu = per_cu;
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
+ continue;
+
if (full_path != NULL)
{
const char *this_real_name = dw2_get_real_path (objfile,
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 6012118..6c4507d 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -134,6 +134,7 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
const char *full_path, const char *real_path)
{
struct partial_symtab *pst;
+ const char *name_basename = lbasename (name);
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
@@ -142,6 +143,12 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
return (pst);
}
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (name_basename, lbasename (pst->filename)) != 0)
+ continue;
+
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path. */
if (full_path != NULL)
@@ -172,7 +179,7 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
/* Now, search for a matching tail (only if name doesn't have any dirs). */
- if (lbasename (name) == name)
+ if (name_basename == name)
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 1628f31..3d94e6b 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -112,6 +112,11 @@ void _initialize_symtab (void);
/* */
+/* Non-zero if a file may be known by two different basenames.
+ This is the uncommon case, and significantly slows down gdb.
+ Default set to "off" to not slow down the common case. */
+int basenames_may_differ = 0;
+
/* Allow the user to configure the debugger behavior with respect
to multiple-choice menus when more than one symbol matches during
a symbol lookup. */
@@ -155,6 +160,7 @@ lookup_symtab (const char *name)
char *real_path = NULL;
char *full_path = NULL;
struct cleanup *cleanup;
+ const char* base_name = lbasename (name);
cleanup = make_cleanup (null_cleanup, NULL);
@@ -180,6 +186,12 @@ got_symtab:
return s;
}
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
+ continue;
+
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path. */
@@ -4885,5 +4897,19 @@ Show how the debugger handles ambiguities in expressions."), _("\
Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
NULL, NULL, &setlist, &showlist);
+ add_setshow_boolean_cmd ("basenames-may-differ", class_obscure,
+ &basenames_may_differ, _("\
+Set whether a source file may have multiple base names."), _("\
+Show whether a source file may have multiple base names."), _("\
+(A \"base name\" is the name of a file with the directory part removed.\n\
+Example: The base name of \"/home/user/hello.c\" is \"hello.c\".)\n\
+If set, GDB will canonicalize file names (e.g., expand symlinks)\n\
+before comparing them. Canonicalization is an expensive operation,\n\
+but it allows the same file be known by more than one base name.\n\
+If not set (the default), all source files are assumed to have just\n\
+one base name, and gdb will do file name comparisons more efficiently."),
+ NULL, NULL,
+ &setlist, &showlist);
+
observer_attach_executable_changed (symtab_observer_executable_changed);
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index e5bf155..39a61f4 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1306,4 +1306,6 @@ void fixup_section (struct general_symbol_info *ginfo,
struct objfile *lookup_objfile_from_block (const struct block *block);
+extern int basenames_may_differ;
+
#endif /* !defined(SYMTAB_H) */