* NEWS: Mention new parameter basenames-may-differ.
authorDoug Evans <dje@google.com>
Tue, 15 Nov 2011 17:40:02 +0000 (17:40 +0000)
committerDoug Evans <dje@google.com>
Tue, 15 Nov 2011 17:40:02 +0000 (17:40 +0000)
* 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.

doc/
* gdb.texinfo (Files): Document basenames-may-differ.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/dwarf2read.c
gdb/psymtab.c
gdb/symtab.c
gdb/symtab.h

index 2e866ba..98f7c7d 100644 (file)
@@ -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>
 
index bce8e3c..c4e59c4 100644 (file)
--- 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
index 15659d6..4975cd2 100644 (file)
@@ -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 "!".
index 9255b89..f4f7f1e 100644 (file)
@@ -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
index 5e5ee7c..5e279de 100644 (file)
@@ -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,
index 6012118..6c4507d 100644 (file)
@@ -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)
index 1628f31..3d94e6b 100644 (file)
@@ -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);
 }
index e5bf155..39a61f4 100644 (file)
@@ -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) */