From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 55613 invoked by alias); 20 Oct 2017 19:21:12 -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 55604 invoked by uid 89); 20 Oct 2017 19:21:11 -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= 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, 20 Oct 2017 19:21:09 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AD9F883F42 for ; Fri, 20 Oct 2017 19:21:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AD9F883F42 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=keiths@redhat.com Received: from valrhona.uglyboxes.com (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 88F2E5C1A3 for ; Fri, 20 Oct 2017 19:21:08 +0000 (UTC) Subject: Re: [PATCH 2/2] Report stop locations in inlined functions. To: gdb-patches@sourceware.org References: <1499740601-15957-1-git-send-email-keiths@redhat.com> <1499740601-15957-2-git-send-email-keiths@redhat.com> <4bfba041-22f5-1650-1f83-0f8860f202fb@redhat.com> <17ac2bdc-cd7b-d8f1-bf75-056fe87ca916@redhat.com> From: Keith Seitz Message-ID: Date: Fri, 20 Oct 2017 19:21:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <17ac2bdc-cd7b-d8f1-bf75-056fe87ca916@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2017-10/txt/msg00681.txt.bz2 On 07/18/2017 10:46 AM, Pedro Alves wrote: > Maybe we need to move this bit in infrun.c: > > /* See if there is a breakpoint/watchpoint/catchpoint/etc. that > handles this event. */ > ecs->event_thread->control.stop_bpstat > = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), > stop_pc, ecs->ptid, &ecs->ws, stop_chain); > > a bit above, before the skip_inline_frames call, and then > you don't even need to pass down the bpstat to skip_inline_frames, > as you can then access it from the thread directly? I've tried this approach, and it causes a single test regression in gdb.python/py-finish-breakpoint.exp. It's taken me quite some time to figure out what was happening, but the key is that the regressing test involved a breakpoint condition that was an inferior function call (which failed). In that case, the global inline frame state was left with a stray inline frame and the assertion in skip_inline_frames was triggered. There are two ways to fix this. The easy way is to call clear_inline_frame_state sometime after the exception occurred, such as where the exception is caught in bpstat_check_breakpoint_conditions(*1). I'm not entirely confident that doing this every time is safe, so I'm leaning toward option #2. The "more" complex option is to only create the stop_chain, later passing it to bpstat_stop_status(*2). This avoids checking the breakpoint condition before calling skip_inline_frames, avoiding the exception problem altogether. If you've a preference, I'd like to hear it. Keith *1 The "simpler" solution (for illustration only) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 32ceea7..4d2ebd8 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -68,6 +68,7 @@ #include "format.h" #include "thread-fsm.h" #include "tid-parse.h" +#include "inline-frame.h" /* readline include files */ #include "readline/readline.h" @@ -5359,6 +5360,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid) } CATCH (ex, RETURN_MASK_ALL) { + clear_inline_frame_state (ptid); exception_fprintf (gdb_stderr, ex, "Error in testing breakpoint condition:\n"); } diff --git a/gdb/infrun.c b/gdb/infrun.c index d00c5f6..60fd166 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -5864,6 +5864,12 @@ handle_signal_stop (struct execution_control_state *ecs) stop_print_frame = 1; stopped_by_random_signal = 0; + /* See if there is a breakpoint/watchpoint/catchpoint/etc. that + handles this event. */ + ecs->event_thread->control.stop_bpstat + = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), + stop_pc, ecs->ptid, &ecs->ws); + /* Hide inlined functions starting here, unless we just performed stepi or nexti. After stepi and nexti, always show the innermost frame (not any inline function call sites). */ @@ -5894,7 +5900,12 @@ handle_signal_stop (struct execution_control_state *ecs) ecs->event_thread->prev_pc, &ecs->ws))) { - skip_inline_frames (ecs->ptid); + struct breakpoint *bpt = NULL; + + if (ecs->event_thread->control.stop_bpstat != NULL) + bpt = ecs->event_thread->control.stop_bpstat->breakpoint_at; + + skip_inline_frames (ecs->ptid, bpt); /* Re-fetch current thread's frame in case that invalidated the frame cache. */ @@ -5939,12 +5950,6 @@ handle_signal_stop (struct execution_control_state *ecs) } } - /* See if there is a breakpoint/watchpoint/catchpoint/etc. that - handles this event. */ - ecs->event_thread->control.stop_bpstat - = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), - stop_pc, ecs->ptid, &ecs->ws); - /* Following in case break condition called a function. */ stop_print_frame = 1; *2 The more "complex," safer solution (for illustration only) diff --git a/gdb/infrun.c b/gdb/infrun.c index d00c5f6..8c70aba 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -5863,6 +5863,7 @@ handle_signal_stop (struct execution_control_state *ecs) ecs->event_thread->control.stop_step = 0; stop_print_frame = 1; stopped_by_random_signal = 0; + bpstat stop_chain = NULL; /* Hide inlined functions starting here, unless we just performed stepi or nexti. After stepi and nexti, always show the innermost frame (not any @@ -5894,7 +5895,13 @@ handle_signal_stop (struct execution_control_state *ecs) ecs->event_thread->prev_pc, &ecs->ws))) { - skip_inline_frames (ecs->ptid); + struct breakpoint *bpt = NULL; + + stop_chain = build_bpstat_chain (aspace, stop_pc, &ecs->ws); + if (stop_chain != NULL) + bpt = stop_chain->breakpoint_at; + + skip_inline_frames (ecs->ptid, bpt); /* Re-fetch current thread's frame in case that invalidated the frame cache. */ @@ -5943,7 +5950,7 @@ handle_signal_stop (struct execution_control_state *ecs) handles this event. */ ecs->event_thread->control.stop_bpstat = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), - stop_pc, ecs->ptid, &ecs->ws); + stop_pc, ecs->ptid, &ecs->ws, stop_chain); /* Following in case break condition called a function. */