From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id SQEcFsXjSWHMSwAAWB0awg (envelope-from ) for ; Tue, 21 Sep 2021 09:53:09 -0400 Received: by simark.ca (Postfix, from userid 112) id 47C301EE25; Tue, 21 Sep 2021 09:53:09 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 08A5B1EDF7 for ; Tue, 21 Sep 2021 09:53:07 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F190D3858403 for ; Tue, 21 Sep 2021 13:53:05 +0000 (GMT) Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by sourceware.org (Postfix) with ESMTPS id 922E33858C3A for ; Tue, 21 Sep 2021 13:52:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 922E33858C3A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x42d.google.com with SMTP id w17so31309352wrv.10 for ; Tue, 21 Sep 2021 06:52:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=z5661nQu0WYv3rgBGiikLW4+0n+isjPfrJSAOjegpjA=; b=JNjstk8ZYldIh427auFuBkdBKJe2KJOslwSX8C98HR/rLZjjx2Cta/jD6JwR4uZtHS oUql56WHjW49m9V1KotT8pEc9hkmkluxKr+ZNbZo7nIPMbvUiJBhWOt0yua+MXBZ32lm YBTBBI4fHLOAyGqO+Q1d7f3kzDcrrD4yGbtwiWeYRYADX2Zoe+h1CEXqLEOtVJau5P78 RVxZN6hytUtcHjciuZ9yFvVauwkvY655Uj4V9iI++SAEyaObDmcbnLRQzOxwQDCpCCXp tGUkwEOD+ohvrx0lz5H95iiORAc/JrSj+Mml7CAIrrelMuQr5tEPzvuP4ZH1Dkkux2v1 6Nzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=z5661nQu0WYv3rgBGiikLW4+0n+isjPfrJSAOjegpjA=; b=TIAZNHM3tsD1IHQf96z9lAnC+t6sQHy+AK8RB3WIycjy3p7FIQAypmkXAEFF3NtF7N q5qOAa2TTYIPSDIDWs4lWyWf8DykgcIB76EpCODB9PhbnKAaDt2KOT/ux+1OpfdvCQZz 5ObBSh13UxXu+0U+ofxenLaSsV2uxEeKNAMG6fED/4xsLLOJc5b9J6CAN6QMibJbnIuS nIaFa7L2HlSz13hqu4impGYG+J8nn4Ustx3NCp+lLL2kIgkAe8EwiD49VRqAwzjqly3R mTYqW5+9blARzBiGzxSfJrG91VCAGgXK5f93xg/wy1qDyMEDrivzCYm8AQEMuVSVHhxi 4lMw== X-Gm-Message-State: AOAM533jOehyoviy677LyIzTzUQmK9cuFKl8v1guRXttgADjb0/XKM6a 915J/b6KqUKxPsC/y8g0qbWzSA== X-Google-Smtp-Source: ABdhPJykaMvbV3zWxkn7p3Qvjy7VvNHV3KgnjoQJ5cW/bpfuXqzJKkLVwpbOE6+VjXBc286K6wZeow== X-Received: by 2002:a5d:53c8:: with SMTP id a8mr35016785wrw.168.1632232373352; Tue, 21 Sep 2021 06:52:53 -0700 (PDT) Received: from localhost (host86-153-58-62.range86-153.btcentralplus.com. [86.153.58.62]) by smtp.gmail.com with ESMTPSA id x13sm19469909wrg.62.2021.09.21.06.52.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Sep 2021 06:52:52 -0700 (PDT) Date: Tue, 21 Sep 2021 14:52:51 +0100 From: Andrew Burgess To: Pedro Alves Subject: Re: [PATCHv5] gdb: prevent an assertion when computing the frame_id for an inline frame Message-ID: <20210921135251.GE4950@embecosm.com> References: <20210727101003.2910993-1-andrew.burgess@embecosm.com> <20210809154122.3468792-1-andrew.burgess@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: Linux/5.8.18-100.fc31.x86_64 (x86_64) X-Uptime: 14:48:13 up 2 days, 4:57, X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gdb-patches@sourceware.org Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" * Pedro Alves [2021-09-20 13:24:50 +0100]: > Hi Andrew, > > On 2021-08-09 4:41 p.m., Andrew Burgess wrote: > > I've not heard anything from Pedro, but I'd like to move this patch > > forward. > > > > My assumption is that Pedro doesn't like using exceptions to pass > > around information for a case that maybe isn't that exceptional. As > > Pedro was happy with v2, this new patch removes the use of exceptions. > > > > Simon's concerns with v1/v2 were, I think, summarised as: > > > > 1. What get_prev_frame_if_no_cycle does no longer matches the > > function name, and > > > > 2. get_prev_frame_if_no_cycle was trying to figure out the callers > > intention in order to change its behaviour. > > > > To try and address these two things I have: > > > > 1. Renamed get_prev_frame_if_no_cycle to hopefully make it clearer > > that its result is not so clear cut, and > > > > 2. Changed the behaviour of get_prev_frame_if_no_cycle based on a > > passed in parameter instead of "peeking" at various bits of state. > > > > My hope is that this might be more acceptable to everyone, but I'd > > love to hear any thoughts, > > > > To be honest, to me, the new "cycle_detection_p" argument seems pointless/redundant, > since inside the function, you have the INLINE_FRAME assertion checks anyhow. I.e., > putting: > > bool cycle_detection_p = get_frame_type (this_frame) != INLINE_FRAME; > > inside get_prev_frame_with_optional_cycle_detection yields the exact same, IIUC. > > So adding the argument is just adding scope for someone passing the wrong > cycle_detection_p argument at some point, it seems to me. > > frame.c already has to know special things about inline frames, I mean, > even get_prev_frame_always_1 already must know to bypass a bunch of tests > for inline frames, like: > > /* If we are unwinding from an inline frame, all of the below tests > were already performed when we unwound from the next non-inline > frame. We must skip them, since we can not get THIS_FRAME's ID > until we have unwound all the way down to the previous non-inline > frame. */ > if (get_frame_type (this_frame) == INLINE_FRAME) > return get_prev_frame_if_no_cycle (this_frame); > > > I'd remove the cycle_detection_p argument, replacing it said local: > > bool cycle_detection_p = get_frame_type (this_frame) != INLINE_FRAME; > > and rename get_prev_frame_if_no_cycle to, say, get_prev_frame_maybe_check_cycle. > > Like, e.g.: > > ~~~~ > diff --git a/gdb/frame.c b/gdb/frame.c > index 6433e9db788..2c9a324c93f 100644 > --- a/gdb/frame.c > +++ b/gdb/frame.c > @@ -2051,16 +2051,14 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum, > the previous frame is a duplicate and we return nullptr then we will be > unable to calculate the frame_id of the inline frame, this in turn > causes inline_frame_this_id() to fail. So for inline frames (and only > - for inline frames) it is acceptable to pass CYCLE_DETECTION_P as false, > - in that case the previous frame will always be returned, even when it > + for inline frames), the previous frame will always be returned, even when it > has a duplicate frame_id. We're not worried about cycles in the frame > chain as, if the previous frame returned here has a duplicate frame_id, > then the frame_id of the inline frame, calculated based off the frame_id > of the previous frame, should also be a duplicate. */ > > static struct frame_info * > -get_prev_frame_with_optional_cycle_detection (struct frame_info *this_frame, > - bool cycle_detection_p) > +get_prev_frame_maybe_check_cycle (struct frame_info *this_frame) > { > struct frame_info *prev_frame; > > @@ -2083,6 +2081,9 @@ get_prev_frame_with_optional_cycle_detection (struct frame_info *this_frame, > are simpler. For these frames we immediately compute the frame_id, > and so, for those frames, we will always reenter this function with > the frame_id status of COMPUTING. */ > + > + bool cycle_detection_p = get_frame_type (this_frame) != INLINE_FRAME; > + > gdb_assert (cycle_detection_p > || (get_frame_type (this_frame) == INLINE_FRAME > && ((this_frame->level > 0 > @@ -2193,7 +2194,7 @@ get_prev_frame_always_1 (struct frame_info *this_frame) > until we have unwound all the way down to the previous non-inline > frame. */ > if (get_frame_type (this_frame) == INLINE_FRAME) > - return get_prev_frame_with_optional_cycle_detection (this_frame, false); > + return get_prev_frame_maybe_check_cycle (this_frame); > > /* If this_frame is the current frame, then compute and stash its > frame id prior to fetching and computing the frame id of the > @@ -2294,7 +2295,7 @@ get_prev_frame_always_1 (struct frame_info *this_frame) > } > } > > - return get_prev_frame_with_optional_cycle_detection (this_frame, true); > + return get_prev_frame_maybe_check_cycle (this_frame); > } > > /* Return a "struct frame_info" corresponding to the frame that called > ~~~~ Thanks, I think that's a great suggestion. I'll use this in the next version. > > > > > --- a/gdb/inline-frame.c > > +++ b/gdb/inline-frame.c > > @@ -163,7 +163,10 @@ inline_frame_this_id (struct frame_info *this_frame, > > function, there must be previous frames, so this is safe - as > > long as we're careful not to create any cycles. See related > > comments in get_prev_frame_always_1. */ > > - *this_id = get_frame_id (get_prev_frame_always (this_frame)); > > + frame_info *prev_frame = get_prev_frame_always (this_frame); > > + if (prev_frame == nullptr) > > + error ("failed to find previous frame when computing inline frame id"); > > Missing _(). But, is this a "just in case" check/error? As in, a softer > gdb_assert? With the bug fixed, is this error call ever expected to > trigger (modulo other gdb bugs)? No, I don't think this is a softer assert. get_prev_frame_always can return nullptr for other reasons, e.g if a MEMORY_ERROR is thrown while figuring out the previous frame. If that should happen then we'll be back in the original situation, *this_id will be null_frame_id, and the assert that I originally saw will trigger again. I don't see any reason why get_prev_frame_always _shouldn't_ return nullptr here, but if it does I we can't get the inline frame's id. I'll post a new patch with the changes made. Thanks, Andrew