gdb
authorTom Tromey <tromey@redhat.com>
Mon, 16 Jan 2012 20:40:53 +0000 (20:40 +0000)
committerTom Tromey <tromey@redhat.com>
Mon, 16 Jan 2012 20:40:53 +0000 (20:40 +0000)
* NEWS: Add item.
* symtab.h (compare_filenames_for_search): Declare.
* symtab.c (compare_filenames_for_search): New function.
(iterate_over_some_symtabs): Use it.
* symfile.h (struct quick_symbol_functions)
<map_symtabs_matching_filename>: Change spec.
* psymtab.c (partial_map_symtabs_matching_filename): Use
compare_filenames_for_search.  Update for new spec.
* dwarf2read.c (dw2_map_symtabs_matching_filename): Use
compare_filenames_for_search.  Update for new spec.
* breakpoint.c (clear_command): Use compare_filenames_for_search.
gdb/doc
* gdb.texinfo (Specify Location): Document relative file name
handling.
gdb/testsuite
* gdb.linespec/linespec.exp: Change some tests to use $decimal.
Add tests for relative directory.

12 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/breakpoint.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/dwarf2read.c
gdb/psymtab.c
gdb/symfile.h
gdb/symtab.c
gdb/symtab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.linespec/linespec.exp

index dfd4178e62f01c1e57bc9c0b61e97a8756a57706..614141649f0a07abf4f3dcd2cbe446512c3a18af 100644 (file)
@@ -1,3 +1,17 @@
+2012-01-16  Tom Tromey  <tromey@redhat.com>
+
+       * NEWS: Add item.
+       * symtab.h (compare_filenames_for_search): Declare.
+       * symtab.c (compare_filenames_for_search): New function.
+       (iterate_over_some_symtabs): Use it.
+       * symfile.h (struct quick_symbol_functions)
+       <map_symtabs_matching_filename>: Change spec.
+       * psymtab.c (partial_map_symtabs_matching_filename): Use
+       compare_filenames_for_search.  Update for new spec.
+       * dwarf2read.c (dw2_map_symtabs_matching_filename): Use
+       compare_filenames_for_search.  Update for new spec.
+       * breakpoint.c (clear_command): Use compare_filenames_for_search.
+
 2012-01-16  Tom Tromey  <tromey@redhat.com>
 
        PR python/13281:
index 02082a3f17993dc4672a64f7d27671ca39528e40..efb53a7580eee020404e66e2df92a19876f8c2e4 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
   ** A new class, gdb.printing.FlagEnumerationPrinter, can be used to
      apply "flag enum"-style pretty-printing to any enum.
 
+* The filename part of a linespec will now match trailing components
+  of a source file name.  For example, "break gcc/expr.c:1000" will
+  now set a breakpoint in build/gcc/expr.c, but not
+  build/libcpp/expr.c.
+
 *** Changes in GDB 7.4
 
 * GDB now handles ambiguous linespecs more consistently; the existing
index e9d29ff6b4169d191d4e9e56c94fadebb0b45236..f6a0276b8ac73fd9a878a210e1ad7ae7a0df9fb9 100644 (file)
@@ -10070,6 +10070,8 @@ clear_command (char *arg, int from_tty)
   make_cleanup (VEC_cleanup (breakpoint_p), &found);
   for (i = 0; i < sals.nelts; i++)
     {
+      int is_abs, sal_name_len;
+
       /* If exact pc given, clear bpts at that pc.
          If line given (pc == 0), clear all bpts on specified line.
          If defaulting, clear all bpts on default line
@@ -10083,6 +10085,8 @@ clear_command (char *arg, int from_tty)
          1              0             <can't happen> */
 
       sal = sals.sals[i];
+      is_abs = sal.symtab == NULL ? 1 : IS_ABSOLUTE_PATH (sal.symtab->filename);
+      sal_name_len = is_abs ? 0 : strlen (sal.symtab->filename);
 
       /* Find all matching breakpoints and add them to 'found'.  */
       ALL_BREAKPOINTS (b)
@@ -10102,13 +10106,24 @@ clear_command (char *arg, int from_tty)
                                  && (loc->address == sal.pc)
                                  && (!section_is_overlay (loc->section)
                                      || loc->section == sal.section));
-                 int line_match = ((default_match || sal.explicit_line)
-                                   && loc->source_file != NULL
-                                   && sal.symtab != NULL
-                                   && sal.pspace == loc->pspace
-                                   && filename_cmp (loc->source_file,
-                                                    sal.symtab->filename) == 0
-                                   && loc->line_number == sal.line);
+                 int line_match = 0;
+
+                 if ((default_match || sal.explicit_line)
+                     && loc->source_file != NULL
+                     && sal.symtab != NULL
+                     && sal.pspace == loc->pspace
+                     && loc->line_number == sal.line)
+                   {
+                     if (filename_cmp (loc->source_file,
+                                       sal.symtab->filename) == 0)
+                       line_match = 1;
+                     else if (!IS_ABSOLUTE_PATH (sal.symtab->filename)
+                              && compare_filenames_for_search (loc->source_file,
+                                                               sal.symtab->filename,
+                                                               sal_name_len))
+                       line_match = 1;
+                   }
+
                  if (pc_match || line_match)
                    {
                      match = 1;
index fb9ea01e01b168cc7fdb03c350574a06575cfb5b..e5a0dacee7747a6968ff1fe92dec0cb3e2cdafff 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-16  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.texinfo (Specify Location): Document relative file name
+       handling.
+
 2012-01-16  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (gdb.printing): Document FlagEnumerationPrinter.
index de2e39005fbe1d9ef651b71906694414d6cebbfe..49db18933bda3c7c14c6f521e0214e0a2eb9f648 100644 (file)
@@ -6492,6 +6492,11 @@ linespec.
 
 @item @var{filename}:@var{linenum}
 Specifies the line @var{linenum} in the source file @var{filename}.
+If @var{filename} is a relative file name, then it will match any
+source file name with the same trailing components.  For example, if
+@var{filename} is @samp{gcc/expr.c}, then it will match source file
+name of @file{/build/trunk/gcc/expr.c}, but not
+@file{/build/trunk/libcpp/expr.c} or @file{/build/trunk/gcc/x-expr.c}.
 
 @item @var{function}
 Specifies the line that begins the body of the function @var{function}.
index afb43374526e1c55ffa5266d3a357cec01309fc3..0ef0a5b38d58eb1245edc46f47d57b8f447bc5f5 100644 (file)
@@ -2403,8 +2403,8 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
 {
   int i;
   const char *name_basename = lbasename (name);
-  int check_basename = name_basename == name;
-  struct dwarf2_per_cu_data *base_cu = NULL;
+  int name_len = strlen (name);
+  int is_abs = IS_ABSOLUTE_PATH (name);
 
   dw2_setup (objfile);
 
@@ -2427,7 +2427,9 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
        {
          const char *this_name = file_data->file_names[j];
 
-         if (FILENAME_CMP (name, this_name) == 0)
+         if (FILENAME_CMP (name, this_name) == 0
+             || (!is_abs && compare_filenames_for_search (this_name,
+                                                          name, name_len)))
            {
              if (dw2_map_expand_apply (objfile, per_cu,
                                        name, full_path, real_path,
@@ -2435,9 +2437,12 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
                return 1;
            }
 
-         if (check_basename && ! base_cu
-             && FILENAME_CMP (lbasename (this_name), name) == 0)
-           base_cu = per_cu;
+           {
+             if (dw2_map_expand_apply (objfile, per_cu,
+                                       name, full_path, real_path,
+                                       callback, data))
+               return 1;
+           }
 
          /* Before we invoke realpath, which can get expensive when many
             files are involved, do a quick comparison of the basenames.  */
@@ -2451,7 +2456,10 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
                                                              file_data, j);
 
              if (this_real_name != NULL
-                 && FILENAME_CMP (full_path, this_real_name) == 0)
+                 && (FILENAME_CMP (full_path, this_real_name) == 0
+                     || (!is_abs
+                         && compare_filenames_for_search (this_real_name,
+                                                          name, name_len))))
                {
                  if (dw2_map_expand_apply (objfile, per_cu,
                                            name, full_path, real_path,
@@ -2466,7 +2474,10 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
                                                              file_data, j);
 
              if (this_real_name != NULL
-                 && FILENAME_CMP (real_path, this_real_name) == 0)
+                 && (FILENAME_CMP (real_path, this_real_name) == 0
+                     || (!is_abs
+                         && compare_filenames_for_search (this_real_name,
+                                                          name, name_len))))
                {
                  if (dw2_map_expand_apply (objfile, per_cu,
                                            name, full_path, real_path,
@@ -2477,14 +2488,6 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
        }
     }
 
-  if (base_cu)
-    {
-      if (dw2_map_expand_apply (objfile, base_cu,
-                               name, full_path, real_path,
-                               callback, data))
-       return 1;
-    }
-
   return 0;
 }
 
index 1f9457f7e3bb6bc0116f60490dd198909094311b..998bc05b7309a842d288f0d5ec86d674ab903a07 100644 (file)
@@ -164,10 +164,14 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
 {
   struct partial_symtab *pst;
   const char *name_basename = lbasename (name);
+  int name_len = strlen (name);
+  int is_abs = IS_ABSOLUTE_PATH (name);
 
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
   {
-    if (FILENAME_CMP (name, pst->filename) == 0)
+    if (FILENAME_CMP (name, pst->filename) == 0
+       || (!is_abs && compare_filenames_for_search (pst->filename,
+                                                    name, name_len)))
       {
        if (partial_map_expand_apply (objfile, name, full_path, real_path,
                                      pst, callback, data))
@@ -186,7 +190,9 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
       {
        psymtab_to_fullname (pst);
        if (pst->fullname != NULL
-           && FILENAME_CMP (full_path, pst->fullname) == 0)
+           && (FILENAME_CMP (full_path, pst->fullname) == 0
+               || (!is_abs && compare_filenames_for_search (pst->fullname,
+                                                            name, name_len))))
          {
            if (partial_map_expand_apply (objfile, name, full_path, real_path,
                                          pst, callback, data))
@@ -203,7 +209,10 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
             rp = gdb_realpath (pst->fullname);
             make_cleanup (xfree, rp);
           }
-       if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
+       if (rp != NULL
+           && (FILENAME_CMP (real_path, rp) == 0
+               || (!is_abs && compare_filenames_for_search (real_path,
+                                                            name, name_len))))
          {
            if (partial_map_expand_apply (objfile, name, full_path, real_path,
                                          pst, callback, data))
@@ -212,17 +221,6 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
       }
   }
 
-  /* Now, search for a matching tail (only if name doesn't have any dirs).  */
-
-  if (name_basename == name)
-    ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
-    {
-      if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
-       if (partial_map_expand_apply (objfile, name, full_path, real_path, pst,
-                                     callback, data))
-         return 1;
-    }
-
   return 0;
 }
 
index 6d3916256bcf185c808b8a965249c407a68a2839..6b664cd36b2966d26015fb370bd1de89b029d44f 100644 (file)
@@ -153,7 +153,7 @@ struct quick_symbol_functions
   /* Expand and iterate over each "partial" symbol table in OBJFILE
      where the source file is named NAME.
 
-     If there is no '/' in the name, a match after a '/' in the symbol
+     If NAME is not absolute, a match after a '/' in the symbol
      table's file name will also work.  FULL_PATH is the absolute file
      name, and REAL_PATH is the same, run through gdb_realpath.
 
index ab6a1aa40cbafe1054e76313b084c437fdc4cc1e..1746d69a3e8bb0d0b25f2991e59a98234535dcfd 100644 (file)
@@ -145,6 +145,35 @@ multiple_symbols_select_mode (void)
 
 const struct block *block_found;
 
+/* See whether FILENAME matches SEARCH_NAME using the rule that we
+   advertise to the user.  (The manual's description of linespecs
+   describes what we advertise).  SEARCH_LEN is the length of
+   SEARCH_NAME.  We assume that SEARCH_NAME is a relative path.
+   Returns true if they match, false otherwise.  */
+
+int
+compare_filenames_for_search (const char *filename, const char *search_name,
+                             int search_len)
+{
+  int len = strlen (filename);
+  int offset;
+
+  if (len < search_len)
+    return 0;
+
+  /* The tail of FILENAME must match.  */
+  if (FILENAME_CMP (filename + len - search_len, search_name) != 0)
+    return 0;
+
+  /* Either the names must completely match, or the character
+     preceding the trailing SEARCH_NAME segment of FILENAME must be a
+     directory separator.  */
+  return (len == search_len
+         || IS_DIR_SEPARATOR (filename[len - search_len - 1])
+         || (HAS_DRIVE_SPEC (filename)
+             && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len]));
+}
+
 /* Check for a symtab of a specific name by searching some symtabs.
    This is a helper function for callbacks of iterate_over_symtabs.
 
@@ -169,15 +198,24 @@ iterate_over_some_symtabs (const char *name,
   struct symtab *s = NULL;
   struct cleanup *cleanup;
   const char* base_name = lbasename (name);
+  int name_len = strlen (name);
+  int is_abs = IS_ABSOLUTE_PATH (name);
 
   for (s = first; s != NULL && s != after_last; s = s->next)
     {
+      /* Exact match is always ok.  */
       if (FILENAME_CMP (name, s->filename) == 0)
        {
          if (callback (s, data))
            return 1;
        }
 
+      if (!is_abs && compare_filenames_for_search (s->filename, name, name_len))
+       {
+         if (callback (s, data))
+           return 1;
+       }
+
     /* Before we invoke realpath, which can get expensive when many
        files are involved, do a quick comparison of the basenames.  */
     if (! basenames_may_differ
@@ -196,6 +234,13 @@ iterate_over_some_symtabs (const char *name,
            if (callback (s, data))
              return 1;
           }
+
+       if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name,
+                                                                  name_len))
+         {
+           if (callback (s, data))
+             return 1;
+         }
       }
 
     if (real_path != NULL)
@@ -212,24 +257,16 @@ iterate_over_some_symtabs (const char *name,
                if (callback (s, data))
                  return 1;
              }
+
+           if (!is_abs && compare_filenames_for_search (rp, name, name_len))
+             {
+               if (callback (s, data))
+                 return 1;
+             }
           }
       }
     }
 
-  /* Now, search for a matching tail (only if name doesn't have any dirs).  */
-
-  if (lbasename (name) == name)
-    {
-      for (s = first; s != NULL && s != after_last; s = s->next)
-       {
-         if (FILENAME_CMP (lbasename (s->filename), name) == 0)
-           {
-             if (callback (s, data))
-               return 1;
-           }
-       }
-    }
-
   return 0;
 }
 
index 7b96ab3c6f7efea58c0cbb559c8a3f37eae72a01..4836dd6d16dc78cbdc320ee1cb2c0c7e0a511663 100644 (file)
@@ -1239,6 +1239,10 @@ struct objfile *lookup_objfile_from_block (const struct block *block);
 
 extern int basenames_may_differ;
 
+int compare_filenames_for_search (const char *filename,
+                                 const char *search_name,
+                                 int search_len);
+
 int iterate_over_some_symtabs (const char *name,
                               const char *full_path,
                               const char *real_path,
index abb08b966edf7f14b14a217cbed9b74b3dcf678b..88a56be8a98ac31aa9134c8368cb7843be0e2a04 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-16  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.linespec/linespec.exp: Change some tests to use $decimal.
+       Add tests for relative directory.
+
 2012-01-16  Tom Tromey  <tromey@redhat.com>
 
        * gdb.base/printcmds.c (enum flag_enum): New.
index 4ac2fd8552c54b7a036b0ed82c5a82b9f1632093..92be31c4aa424c7b3285a12a35d92bc24429b4ff 100644 (file)
@@ -44,19 +44,24 @@ if {$l1 != $l2} {
     error "somebody incompatibly modified the source files needed by linespec.exp"
 }
 
+gdb_test "break one/thefile.cc:$l1" \
+    "Breakpoint $decimal at $hex: file .*thefile.cc, line $l1." \
+    "single-location break using dir/file:line"
+
+gdb_test "clear one/thefile.cc:$l1" \
+    "Deleted breakpoint $decimal *" \
+    "clear breakpoint using dir/file:line"
+
 gdb_test "break thefile.cc:$l1" \
-    "Breakpoint 1 at $hex: thefile.cc:$l1. \[(\]2 locations\[)\]" \
+    "Breakpoint $decimal at $hex: thefile.cc:$l1. \[(\]2 locations\[)\]" \
     "multi-location break using file:line"
 
-# We'd like this to work, but it currently does not.
-# gdb_test "break one/thefile.cc:$l1"
-
 gdb_test "break dupname" \
-    "Breakpoint 2 at $hex: dupname. \[(\]2 locations\[)\]" \
+    "Breakpoint $decimal at $hex: dupname. \[(\]2 locations\[)\]" \
     "multi-location break using duplicate function name"
 
 gdb_test "break dupname:label" \
-    "Breakpoint 3 at $hex: dupname:label. \[(\]2 locations\[)\]" \
+    "Breakpoint $decimal at $hex: dupname:label. \[(\]2 locations\[)\]" \
     "multi-location break using duplicate function name and label"
 
 gdb_test_no_output "set breakpoint pending off" \