summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/NEWS5
-rw-r--r--gdb/breakpoint.c29
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo5
-rw-r--r--gdb/dwarf2read.c35
-rw-r--r--gdb/psymtab.c26
-rw-r--r--gdb/symfile.h2
-rw-r--r--gdb/symtab.c65
-rw-r--r--gdb/symtab.h4
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.linespec/linespec.exp17
12 files changed, 154 insertions, 58 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dfd4178e62f..614141649f0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
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:
* gdbtypes.h (TYPE_FLAG_ENUM): New macro.
(struct main_type) <flag_flag_enum>: New field.
diff --git a/gdb/NEWS b/gdb/NEWS
index 02082a3f179..efb53a7580e 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -25,6 +25,11 @@
** 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
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index e9d29ff6b41..f6a0276b8ac 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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;
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index fb9ea01e01b..e5a0dacee77 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,5 +1,10 @@
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.
2012-01-13 Jan Kratochvil <jan.kratochvil@redhat.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index de2e39005fb..49db18933bd 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -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}.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index afb43374526..0ef0a5b38d5 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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;
}
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 1f9457f7e3b..998bc05b730 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -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;
}
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 6d3916256bc..6b664cd36b2 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -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.
diff --git a/gdb/symtab.c b/gdb/symtab.c
index ab6a1aa40cb..1746d69a3e8 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -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;
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 7b96ab3c6f7..4836dd6d16d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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,
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index abb08b966ed..88a56be8a98 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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.
(three): New global.
* gdb.base/printcmds.exp (test_print_enums): Add test for flag
diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp
index 4ac2fd8552c..92be31c4aa4 100644
--- a/gdb/testsuite/gdb.linespec/linespec.exp
+++ b/gdb/testsuite/gdb.linespec/linespec.exp
@@ -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" \