gdb
* 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.
This commit is contained in:
parent
cafec44190
commit
4aac40c837
12 changed files with 154 additions and 58 deletions
|
@ -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:
|
||||
|
|
5
gdb/NEWS
5
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
65
gdb/symtab.c
65
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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" \
|
||||
|
|
Loading…
Reference in a new issue