From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16754 invoked by alias); 16 Jun 2015 17:39:38 -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 16743 invoked by uid 89); 16 Jun 2015 17:39:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,KAM_WEIRDTRICK1,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 Jun 2015 17:39:35 +0000 Received: from svr-orw-fem-04.mgc.mentorg.com ([147.34.97.41]) by relay1.mentorg.com with esmtp id 1Z4upg-00050f-8v from Luis_Gustavo@mentor.com ; Tue, 16 Jun 2015 10:39:32 -0700 Received: from [172.30.7.9] (147.34.91.1) by svr-orw-fem-04.mgc.mentorg.com (147.34.97.41) with Microsoft SMTP Server id 14.3.224.2; Tue, 16 Jun 2015 10:39:31 -0700 Message-ID: <55805F52.20805@codesourcery.com> Date: Tue, 16 Jun 2015 17:39:00 -0000 From: Luis Machado Reply-To: Luis Machado User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Pedro Alves , Subject: Re: [PATCH] Fix problems with finishing a dummy function call on simulators. References: <1433862056-18237-1-git-send-email-lgustavo@codesourcery.com> <55772797.802@redhat.com> In-Reply-To: <55772797.802@redhat.com> Content-Type: multipart/mixed; boundary="------------090301040404050201050104" X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg00351.txt.bz2 --------------090301040404050201050104 Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 4494 On 06/09/2015 02:51 PM, Pedro Alves wrote: > On 06/09/2015 04:00 PM, Luis Machado wrote: >> This is in line with what was done by Joel's patch here: >> >> https://sourceware.org/ml/gdb-patches/2014-11/msg00478.html >> >> And it also answers Pedro's question about whether this is specific to SPARC >> QEMU or not. This indeed seems to affect multiple QEMU targets and also other >> simulators (proprietary). > > Sounds like a different issue, although related. > >> >> I ran into this weird issue of not being able to "finish" an inferior function >> call. It looks as if the program is running away, but it really is stuck >> somewhere. "finish" still works fine for regular functions not called manually >> by GDB. > > Sounds like that would fail on SPARC qemu as well. > >> >> I tracked this failure down to GDB having both a bp_call_dummy and bp_finish in >> its breakpoint list. As a result of one not being considered permanent and the >> other considered permanent, GDB will not issue a Z packet to force the insertion >> of that location's breakpoint, confusing the simulator that does not know how >> to deal properly with these permanent breakpoints that GDB inserted beforehand. >> >> The attached patch fixes this, though i'm inclined to say we could probably >> check if both bp_call_dummy and bp_finish are present and force the >> insertion of that location's breakpoint. It isn't clear to me where exactly that >> check would go or if it would be cleaner than checking that information in >> the same function Joel used. >> >> I see no regressions on x86-64 and it fixes a bunch of failures for simulator >> targets we use (MIPS and PowerPC to name two). > > If it happens that you "finish" from a normal function, and the finish > breakpoint ends up on top of a real permanent breakpoint, then this patch > will make us end up inserting a breakpoint on top of that permanent > breakpoint. I don't see what's special about finish breakpoints; > it's the address (dummy breakpoint location) that is special. It very much > sounds like that any kind of breakpoint that is placed on top of the dummy > breakpoint ends up with the same issue. E.g., if you stepi out of > the called function, with a software single-step breakpoint, sounds like > GDB will miss inserting the software step breakpoint because that's > at the same address as the dummy breakpoint. > > As a data point, I assume that GDB is considering the non-permanent > dummy breakpoint a duplicate of the permanent finish breakpoint and > then none ends up inserted. Is that right? > > Not exactly sure what to do here. Maybe we should stop considering > permanent and non-permanent breakpoints at the same address as > duplicates. That should result in GDB inserting the non-permanent > one, I think. Or we could get stop marking permanent breakpoints > as always inserted, and let normal breakpoints insert on top of > permanent breakpoints normally. See also: > https://sourceware.org/ml/gdb-patches/2015-03/msg00174.html I gave the strategy of not marking permanent breakpoints/locations as inserted a try, and it fixes the simulator problems i've been seeing with the permanent breakpoint locations. One strange side effect of this change on my local machine (x86-64) is that gdb.threads/attach-many-short-lived-threads.exp gives me PASS instead of FAIL when always-inserted mode is ON. I didn't investigate this further though. Is it known that this testcase is affected by permanent breakpoint locations? For example: XFAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 5: attach (EPERM) PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: no new threads PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: set breakpoint always-inserted on PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: break break_fn PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: break at break_fn: 1 PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: break at break_fn: 2 PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: break at break_fn: 3 PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: reset timer in the inferior PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: print seconds_left PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: detach PASS: gdb.threads/attach-many-short-lived-threads.exp: iter 5: set breakpoint always-inserted off Is this patch what you had in mind? Luis --------------090301040404050201050104 Content-Type: text/x-patch; name="bp_permanent.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="bp_permanent.diff" Content-length: 3056 2015-06-16 Luis Machado * breakpoint.c (make_breakpoint_permanent): Expand comment. Don't mark permanent locations as inserted. (add_location_to_breakpoint): Likewise (update_global_location_list): Don't error out if a permanent breakpoint is not marked inserted. Don't error out if a non-permanent breakpoint location is inserted on top of a permanent breakpoint. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index eb3df02..768ce59 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7440,15 +7440,16 @@ make_breakpoint_permanent (struct breakpoint *b) struct bp_location *bl; /* By definition, permanent breakpoints are already present in the - code. Mark all locations as inserted. For now, - make_breakpoint_permanent is called in just one place, so it's - hard to say if it's reasonable to have permanent breakpoint with - multiple locations or not, but it's easy to implement. */ + code. For now, make_breakpoint_permanent is called in just one place, so + it's hard to say if it's reasonable to have permanent breakpoint with + multiple locations or not, but it's easy to implement. + + Permanent breakpoints are not marked as inserted so we allow other + non-permanent locations at the same address to be inserted on top + of it. This is required due to some targets, simulators mostly, not + dealing properly with hardwired breakpoints in the code. */ for (bl = b->loc; bl; bl = bl->next) - { - bl->permanent = 1; - bl->inserted = 1; - } + bl->permanent = 1; } /* Call this routine when stepping and nexting to enable a breakpoint @@ -8918,11 +8919,10 @@ add_location_to_breakpoint (struct breakpoint *b, set_breakpoint_location_function (loc, sal->explicit_pc || sal->explicit_line); + /* See comment in make_breakpoint_permanent for the reason why we don't mark + permanent breakpoints as always inserted. */ if (bp_loc_is_permanent (loc)) - { - loc->inserted = 1; - loc->permanent = 1; - } + loc->permanent = 1; return loc; } @@ -12438,12 +12438,6 @@ update_global_location_list (enum ugll_insert_mode insert_mode) continue; } - /* Permanent breakpoint should always be inserted. */ - if (loc->permanent && ! loc->inserted) - internal_error (__FILE__, __LINE__, - _("allegedly permanent breakpoint is not " - "actually inserted")); - if (b->type == bp_hardware_watchpoint) loc_first_p = &wp_loc_first; else if (b->type == bp_read_watchpoint) @@ -12479,12 +12473,6 @@ update_global_location_list (enum ugll_insert_mode insert_mode) /* Clear the condition modification flag. */ loc->condition_changed = condition_unchanged; - - if (loc->inserted && !loc->permanent - && (*loc_first_p)->permanent) - internal_error (__FILE__, __LINE__, - _("another breakpoint was inserted on top of " - "a permanent breakpoint")); } if (insert_mode == UGLL_INSERT || breakpoints_should_be_inserted_now ()) --------------090301040404050201050104--