From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23926 invoked by alias); 16 Jan 2012 20:40:30 -0000 Received: (qmail 23904 invoked by uid 22791); 16 Jan 2012 20:40:28 -0000 X-SWARE-Spam-Status: No, hits=-7.0 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_FILL_THIS_FORM_SHORT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 16 Jan 2012 20:40:10 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q0GKeA9T010964 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 16 Jan 2012 15:40:10 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q0GKe74C027088; Mon, 16 Jan 2012 15:40:09 -0500 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id q0GKe5ta021219; Mon, 16 Jan 2012 15:40:06 -0500 From: Tom Tromey To: gdb-patches@sourceware.org Subject: Re: RFC: add relative file name handling for linespecs References: Date: Mon, 16 Jan 2012 21:07:00 -0000 In-Reply-To: (Tom Tromey's message of "Tue, 10 Jan 2012 09:06:08 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-01/txt/msg00577.txt.bz2 >>>>> "Tom" == Tom Tromey writes: Tom> This patch changes gdb to allow relative file names to match a source Tom> file name if all the trailing components match. Previously this Tom> behavior was only allowed if the source file name did not have any Tom> directory separators. Here is the version I am checking in. Built and regtested on x86-64 F15. Some new tests included. Tom 2012-01-16 Tom Tromey * 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) : 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 * gdb.texinfo (Specify Location): Document relative file name handling. 2012-01-16 Tom Tromey * gdb.linespec/linespec.exp: Change some tests to use $decimal. Add tests for relative directory. Index: NEWS =================================================================== RCS file: /cvs/src/src/gdb/NEWS,v retrieving revision 1.480 diff -u -r1.480 NEWS --- NEWS 16 Jan 2012 19:44:13 -0000 1.480 +++ NEWS 16 Jan 2012 20:39:16 -0000 @@ -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 Index: breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.641 diff -u -r1.641 breakpoint.c --- breakpoint.c 16 Jan 2012 17:44:35 -0000 1.641 +++ breakpoint.c 16 Jan 2012 20:39:17 -0000 @@ -10070,6 +10070,8 @@ 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 @@ 1 0 */ 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 @@ && (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: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.607 diff -u -r1.607 dwarf2read.c --- dwarf2read.c 16 Jan 2012 19:44:13 -0000 1.607 +++ dwarf2read.c 16 Jan 2012 20:39:18 -0000 @@ -2403,8 +2403,8 @@ { 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ } } - if (base_cu) - { - if (dw2_map_expand_apply (objfile, base_cu, - name, full_path, real_path, - callback, data)) - return 1; - } - return 0; } Index: psymtab.c =================================================================== RCS file: /cvs/src/src/gdb/psymtab.c,v retrieving revision 1.38 diff -u -r1.38 psymtab.c --- psymtab.c 4 Jan 2012 08:17:09 -0000 1.38 +++ psymtab.c 16 Jan 2012 20:39:18 -0000 @@ -164,10 +164,14 @@ { 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 @@ { 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 @@ 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 @@ } } - /* 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: symfile.h =================================================================== RCS file: /cvs/src/src/gdb/symfile.h,v retrieving revision 1.102 diff -u -r1.102 symfile.h --- symfile.h 4 Jan 2012 08:17:13 -0000 1.102 +++ symfile.h 16 Jan 2012 20:39:18 -0000 @@ -153,7 +153,7 @@ /* 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: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.289 diff -u -r1.289 symtab.c --- symtab.c 4 Jan 2012 08:17:13 -0000 1.289 +++ symtab.c 16 Jan 2012 20:39:19 -0000 @@ -145,6 +145,35 @@ 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 @@ 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 @@ 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 @@ 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: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.197 diff -u -r1.197 symtab.h --- symtab.h 4 Jan 2012 08:17:13 -0000 1.197 +++ symtab.h 16 Jan 2012 20:39:19 -0000 @@ -1239,6 +1239,10 @@ 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: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.912 diff -u -r1.912 gdb.texinfo --- doc/gdb.texinfo 16 Jan 2012 19:44:14 -0000 1.912 +++ doc/gdb.texinfo 16 Jan 2012 20:39:24 -0000 @@ -6492,6 +6492,11 @@ @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: testsuite/gdb.linespec/linespec.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.linespec/linespec.exp,v retrieving revision 1.3 diff -u -r1.3 linespec.exp --- testsuite/gdb.linespec/linespec.exp 4 Jan 2012 08:17:54 -0000 1.3 +++ testsuite/gdb.linespec/linespec.exp 16 Jan 2012 20:39:27 -0000 @@ -44,19 +44,24 @@ 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" \