From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 66755 invoked by alias); 9 Apr 2018 12:25:11 -0000 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 Received: (qmail 66704 invoked by uid 89); 9 Apr 2018 12:25:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-19.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=replied, hitting, fourth X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 09 Apr 2018 12:25:04 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 577A777067 for ; Mon, 9 Apr 2018 12:25:03 +0000 (UTC) Received: from [127.0.0.1] (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8ECC4D7E0D; Mon, 9 Apr 2018 12:25:02 +0000 (UTC) Subject: Re: [PATCH v2] Don't elide all inlined frames To: Keith Seitz , gdb-patches@sourceware.org References: <20180228203324.17579-1-keiths@redhat.com> From: Pedro Alves Message-ID: Date: Mon, 09 Apr 2018 12:25:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <20180228203324.17579-1-keiths@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2018-04/txt/msg00136.txt.bz2 Hi Keith, Somehow I thought I had already replied to this, but apparently not. Here it goes. This is close, but I'm still not clear why the skip_inline_frames loop is how it currently is. See more below. On 02/28/2018 08:33 PM, Keith Seitz wrote: > > void > -skip_inline_frames (ptid_t ptid) > +skip_inline_frames (ptid_t ptid, bpstat stop_chain) > { > CORE_ADDR this_pc; > const struct block *frame_block, *cur_block; > @@ -327,6 +326,36 @@ skip_inline_frames (ptid_t ptid) > if (BLOCK_START (cur_block) == this_pc > || block_starting_point_at (this_pc, cur_block)) > { > + bool skip_this_frame = true; > + > + /* Loop over the stop chain and determine if execution > + stopped in an inlined frame because of a user breakpoint. > + If so do not skip the inlined frame. */ > + for (bpstat s = stop_chain; s != NULL; s = s->next) > + { > + struct breakpoint *bpt = s->breakpoint_at; > + > + if (bpt != NULL && user_breakpoint_p (bpt)) > + { > + for (bp_location *loc = s->bp_location_at; > + loc != NULL; loc = loc->next) > + { > + enum bp_loc_type t = loc->loc_type; > + > + if (loc->address == this_pc > + && (t == bp_loc_software_breakpoint > + || t == bp_loc_hardware_breakpoint)) > + { > + skip_this_frame = false; > + break; > + } > + } > + } > + } > + > + if (!skip_this_frame) > + break; > + It seems my comments from last time still apply here: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Also, to look at the locations, you should look at bpstat->bp_location_at, not at the locations of the breakpoint, because some of the locations of the breakpoint may be disabled/not-inserted, for example. There's one bpstat entry for each _location_ that actually caused a stop, so checking bp_location_at directly saves one loop. (Though you'll add one loop back to walk the bpstat chain, so it's a wash). Careful to not [follow] bpstat->bp_location_at->owner though, see comments in breakpoint.h. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Had you tried that and it didn't work for some reason? Also, this part of the comment: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + > + if (skip_this_frame) > + skip_count++; > last_sym = BLOCK_FUNCTION (cur_block); Couldn't this break out of the outer loop if !skip_this_frame ? Like: if (!skip_this_frame) break; skip_count++; last_sym = BLOCK_FUNCTION (cur_block); ? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The part about breakint out of the outer loop no longer applies as is, but, AFAICT, the current code is still letting the outer stop_chain loop continue iterating even 'if (!skip_this_frame)'? > -gdb_test "continue" \ > - "Breakpoint $decimal, c\\.c_doit2 \\(\\).*" \ > - "Hitting fourth call of read_small" > +for {set i 0} {$i < 4} {incr i} { > + gdb_test "continue" \ > + "Breakpoint $decimal, b\\.read_small \\(\\).*" \ > + "Stopped in read_small ($i)" Let's avoid the trailing " (...)" in test messages/names: https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#Do_not_use_.22tail_parentheses.22_on_test_messages How about for e.g.,: "stopped in read_small, $i" or you can use with_test_prefix, foreach_with_prefix, etc. > --- a/gdb/testsuite/gdb.dwarf2/implptr.exp > +++ b/gdb/testsuite/gdb.dwarf2/implptr.exp > @@ -66,9 +66,13 @@ proc implptr_test_baz {} { > gdb_test "break implptr.c:$line" "Breakpoint 3.*" \ > "set baz breakpoint for implptr" > gdb_continue_to_breakpoint "continue to baz breakpoint for implptr" > + > + # We are breaking in an inlined function. GDB used to stop in the > + # calling frame, but it now stops "in" the inlined function. > + gdb_test "up" "#1 foo .*" I'd suggest avoiding talking about how GDB used to work, because IME that tends to stay behind for years and years and become more noise than signal. I'd suggest something like: # We are breaking in an inlined function. GDB should have stopped # "in" the inlined function, not the calling frame. gdb_test "up" "#1 foo .*" > gdb_test {p p[0].y} " = 92" "sanity check element 0" > gdb_test {p p[1].y} " = 46" "sanity check element 1" > - gdb_test "step" "\r\nadd \\(.*" "enter the inlined function" > + gdb_test "down" "#0 add .*" > gdb_test "p a->y" " = 92" "check element 0 for the offset" > gdb_test "p b->y" " = 46" "check element 1 for the offset" > gdb_continue_to_breakpoint "ignore the second baz breakpoint" > diff --git a/gdb/testsuite/gdb.opt/inline-break.c b/gdb/testsuite/gdb.opt/inline-break.c > +set ws {[\r\n\t ]+} > +set backtrace [list "(in|at)? main"] > +for {set i 3} {$i > 0} {incr i -1} { > + > + foreach inline {"not_inline" "inline"} { > + > + # Check that we stop at the correct location and print out > + # the (possibly) inlined frames. > + set num [gdb_get_line_number "/* ${inline}_func$i */"] > + set pattern ".*/$srcfile:$num${ws}.*$num${ws}int y = $decimal;" Avoid the / before $srcfile for remote host testing. Thanks, Pedro Alves