From patchwork Fri Mar 10 20:59:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Seitz X-Patchwork-Id: 19523 Received: (qmail 63604 invoked by alias); 10 Mar 2017 20:59:18 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 63576 invoked by uid 89); 10 Mar 2017 20:59:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Row, numi, * X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 10 Mar 2017 20:59:14 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 663383A76AB for ; Fri, 10 Mar 2017 20:59:15 +0000 (UTC) Received: from valrhona.uglyboxes.com (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2AKxFba014606 for ; Fri, 10 Mar 2017 15:59:15 -0500 From: Keith Seitz To: gdb-patches@sourceware.org Subject: [PATCH] Use containing function when reporting breakpoint location. Date: Fri, 10 Mar 2017 12:59:13 -0800 Message-Id: <1489179553-4273-1-git-send-email-keiths@redhat.com> X-IsSubscribed: yes print_breakpoint_location currently uses find_pc_sect_function, which always returns the linkage symbol. This essentially means that it skips over any inline frames. Thus, when a breakpoint is set in an inlined function, "info break" may report the calling function as the location of the breakpoint. While pedantically true, it is a little misleading to users: (gdb) b inline_func Breakpoint 1 at 0x400434: file test.c, line 5. (gdb) inf br Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400434 in main at test.c:5 With this patch, print_breakpoint_location now calls a new variation of find_pc_sect_function, find_pc_sect_containing_function, which does not skip over inlined functions, and the breakpoint location is now reported "correctly": (gdb) inf br Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400434 in inline_func at test.c:5 gdb/ChangeLog * blockframe.c (find_pc_sect_containing_function): New function. * breakpoint.c (print_breakpoint_location): Use find_pc_sect_containing_function to avoid skipping inline frames. * symtab.h (find_pc_sect_containing_function): Declare. gdb/testsuite/ChangeLog * gdb.opt/inline-break.exp (break_info_1): New procedure. Use break_info_1 to test "info break" for all breakpoints. --- gdb/ChangeLog | 7 ++++ gdb/blockframe.c | 12 ++++++ gdb/breakpoint.c | 2 +- gdb/symtab.h | 7 ++++ gdb/testsuite/ChangeLog | 5 +++ gdb/testsuite/gdb.opt/inline-break.exp | 75 ++++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e4c4432..87dc913 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2017-MM-DD Keith Seitz + + * blockframe.c (find_pc_sect_containing_function): New function. + * breakpoint.c (print_breakpoint_location): Use + find_pc_sect_containing_function to avoid skipping inline frames. + * symtab.h (find_pc_sect_containing_function): Declare. + 2017-03-10 Keith Seitz PR c++/8218 diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 5ba993c..c602d6b 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -142,6 +142,18 @@ find_pc_sect_function (CORE_ADDR pc, struct obj_section *section) return block_linkage_function (b); } +/* See description in symtab.h. */ + +struct symbol * +find_pc_sect_containing_function (CORE_ADDR pc, struct obj_section *section) +{ + const struct block *b = block_for_pc_sect (pc, section); + + if (b == NULL) + return NULL; + return block_containing_function (b); +} + /* Return the function containing pc value PC. Returns 0 if function is not known. Backward compatibility, no section */ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ab6e9c8..c470f96 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -6154,7 +6154,7 @@ print_breakpoint_location (struct breakpoint *b, else if (loc && loc->symtab) { struct symbol *sym - = find_pc_sect_function (loc->address, loc->section); + = find_pc_sect_containing_function (loc->address, loc->section); if (sym) { uiout->text ("in "); diff --git a/gdb/symtab.h b/gdb/symtab.h index d8c665c..b16cb18 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1336,6 +1336,13 @@ extern struct symbol *find_pc_function (CORE_ADDR); extern struct symbol *find_pc_sect_function (CORE_ADDR, struct obj_section *); +/* Return the function containing pc value PC in section SECTION. + Returns NULL if function is not known. Unlike find_pc_sect_function, + this function does not skip inline frames. */ + +extern struct symbol *find_pc_sect_containing_function (CORE_ADDR, + struct obj_section *); + extern int find_pc_partial_function_gnu_ifunc (CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0718d76..b32136c 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-MM-DD Keith Seitz + + * gdb.opt/inline-break.exp (break_info_1): New procedure. + Use break_info_1 to test "info break" for all breakpoints. + 2017-03-10 Keith Seitz PR c++/8128 diff --git a/gdb/testsuite/gdb.opt/inline-break.exp b/gdb/testsuite/gdb.opt/inline-break.exp index 7be3a34..ff15f1a 100644 --- a/gdb/testsuite/gdb.opt/inline-break.exp +++ b/gdb/testsuite/gdb.opt/inline-break.exp @@ -24,6 +24,61 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ return -1 } +# Return a string that may be used to match the output of "info break NUM". +# +# Optional arguments: +# +# source - the name of the source file +# func - the name of the function +# disp - the breakpoint disposition +# enabled - breakpoint enable state +# locs - number of locations +# line - source line number (ignored without -source) + +proc break_info_1 {num args} { + global decimal + + # Column delimiter + set c {[\t ]+} + + # Row delimiter + set end {[\r\n \t]+} + + # Table header + set header "[join [list Num Type Disp Enb Address What] ${c}]" + + # Get/configure any optional parameters. + parse_args [list {source ""} {func ".*"} {disp "keep"} \ + {enabled "y"} {locs 1} [list line $decimal]] + + if {$source != ""} { + set source "/$source:$line" + } + + # Result starts with the standard header. + set result "$header${end}" + + # Set up for multi-location breakpoint marker. + if {$locs == 1} { + set multi ".*" + } else { + set multi "${end}" + } + append result "[join [list $num breakpoint $disp $enabled $multi] $c]" + + # Add sub-location info. + if {$locs > 1} { + for {set i 1} {$i <= $locs} {incr i} { + append result "[join [list $num.$i $enabled] $c].*" + } + } + + # Add function/source file info. + append result "in $func at .*$source${end}" + + return $result +} + # # func1 is a static inlined function that is called once. # The result should be a single-location breakpoint. @@ -111,3 +166,23 @@ gdb_test "print func1" \ # gdb_test "print func2" \ "\\\$.* = {int \\(int\\)} .* " + +# Test that "info break" reports the location of the breakpoints "inside" +# the inlined functions + +set i 0 +set results([incr i]) [break_info_1 1 -source $srcfile -func "func1"] +set results([incr i]) [break_info_1 2 -locs 2 -source $srcfile -func "func2"] +set results([incr i]) [break_info_1 3 -source $srcfile -func "func3b"] +set results([incr i]) [break_info_1 4 -locs 2 -source $srcfile -func "func4b"] +set results([incr i]) [break_info_1 5 -locs 2 -source $srcfile -func "func5b"] +set results([incr i]) [break_info_1 6 -locs 3 -source $srcfile -func "func6b"] +set results([incr i]) [break_info_1 7 -locs 2 -source $srcfile -func "func7b"] +set results([incr i]) [break_info_1 8 -locs 3 -source $srcfile -func "func8b"] + +for {set i 1} {$i <= [llength [array names results]]} {incr i} { + send_log "Expecting: $results($i)\n" + gdb_test "info break $i" $results($i) +} + +unset -nocomplain results