From patchwork Mon Nov 7 15:53:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60111 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A57B73858293 for ; Mon, 7 Nov 2022 15:53:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A57B73858293 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667836433; bh=7xoT1ooBji0S3/WDRQqLq/qazTURfmpv68ELQeZlb6M=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=kF71sqpdaFl3x8mf16bbykzkR9rgoB2kTRFrx+5TJLHpJNbisoaFVwEusKWMBSkMK 4DY91kgNvSaQt/nGoRsTxHob0sumsCF/aWu35QIGtLT+bwUoIHgZJBwxTEIcKqJDQS 1mqADO6E5kxrz8OjGTuUPSujNbkQKUSJQx/AH7L8= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 3DFF5385841A for ; Mon, 7 Nov 2022 15:53:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3DFF5385841A Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7FrB0l019839 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 10:53:16 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7FrB0l019839 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id 6FD3A1E0D3; Mon, 7 Nov 2022 10:53:11 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 1/7] gdb: clear other.m_cached_id in frame_info_ptr's move ctor Date: Mon, 7 Nov 2022 10:53:04 -0500 Message-Id: <20221107155310.2590069-1-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 15:53:11 +0000 X-Spam-Status: No, score=-3189.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" We do it in the move assignment operator, so I think it makes sense to do it here too for consistency. I don't think it's absolutely necessary to clear the other object's fields (in other words, copy constructor and move constructor could be the same), as there is no exclusive resource being transfered. The important thing is to leave the moved-from object in an unknown, but valid state. But still, I think that clearing the fields of the moved-from object is not a bad idea, it helps ensure we don't rely on the moved-from object after. Change-Id: Iee900ff9d25dad51d62765d694f2e01524351340 Reviewed-By: Bruno Larsen --- gdb/frame-info.h | 1 + 1 file changed, 1 insertion(+) base-commit: 240e07bd94a8da9270c57cde394f6883e43b8497 diff --git a/gdb/frame-info.h b/gdb/frame-info.h index 665f4bdae3bf..7159f82b1962 100644 --- a/gdb/frame-info.h +++ b/gdb/frame-info.h @@ -71,6 +71,7 @@ class frame_info_ptr : public intrusive_list_node : m_ptr (other.m_ptr), m_cached_id (other.m_cached_id) { other.m_ptr = nullptr; + other.m_cached_id = null_frame_id; frame_list.push_back (*this); } From patchwork Mon Nov 7 15:53:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60110 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 35F6238582A7 for ; Mon, 7 Nov 2022 15:53:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 35F6238582A7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667836433; bh=ovMC7nXYgx9U6aTcrzArMAMZ6wu1yxryaqscgKXFaqE=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=U5Q0vhK9cDaaL6HlWC84+bgoph05ejbFz6RlTXdcC5TQ0RF8n6H65VNQnLfSr9lWz k6bxqUjlwe0KILbIlDUH4JjTV8y7pf69ofBMfEt+VXZk8/mdC4/W0NDUp5rEAJnXvD 0PQIWHMIxnlU3W9QqSg08e3nxU3jZUHOJbos2i0Q= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 69EAF385841B for ; Mon, 7 Nov 2022 15:53:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 69EAF385841B Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7FrBLV019843 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 10:53:16 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7FrBLV019843 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id 9E8C81E11F; Mon, 7 Nov 2022 10:53:11 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 2/7] gdb: add prepare_reinflate/reinflate around print_frame_args in info_frame_command_core Date: Mon, 7 Nov 2022 10:53:05 -0500 Message-Id: <20221107155310.2590069-2-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221107155310.2590069-1-simon.marchi@polymtl.ca> References: <20221107155310.2590069-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 15:53:11 +0000 X-Spam-Status: No, score=-3189.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" I noticed this crash: $ ./gdb --data-directory=data-directory -nx -q \ testsuite/outputs/gdb.python/pretty-print-call-by-hand/pretty-print-call-by-hand \ -x testsuite/outputs/gdb.python/pretty-print-call-by-hand/pretty-print-call-by-hand.py \ -ex "b g" -ex r (gdb) info frame Stack level 0, frame at 0x7fffffffdd80: rip = 0x555555555160 in g (/home/simark/src/binutils-gdb/gdb/testsuite/gdb.python/pretty-print-call-by-hand.c:41); saved rip = 0x5555555551a3 called by frame at 0x7fffffffdda0 source language c. Arglist at 0x7fffffffdd70, args: mt=mytype is 0x555555556004 "hello world", depth=10 Fatal signal: Segmentation fault This is another case of frame_info being invalidated under a function's feet. The stack trace when the frame_info get invalidated looks like: ... many frames to pretty print the arg, that eventually invalidate the frame_infos ... #35 0x00005568d0a8ab24 in print_frame_arg (fp_opts=..., arg=0x7ffc3216bcb0) at /home/simark/src/binutils-gdb/gdb/stack.c:489 #36 0x00005568d0a8cc75 in print_frame_args (fp_opts=..., func=0x621000233210, frame=..., num=-1, stream=0x60b000000300) at /home/simark/src/binutils-gdb/gdb/stack.c:898 #37 0x00005568d0a9536d in info_frame_command_core (fi=..., selected_frame_p=true) at /home/simark/src/binutils-gdb/gdb/stack.c:1682 print_frame_args knows that print_frame_arg can invalidate frame_info objects, and therefore calls prepare_reinflate/reinflate. However, info_frame_command_core has a separate frame_info_ptr instance (it is passed by value / copy). So info_frame_command_core needs to know that print_frame_args can invalidate frame_info objects, and therefore needs to prepare_reinflate/reinflate as well. Add those calls, and enhance the gdb.python/pretty-print-call-by-hand.exp test to test that command. Change-Id: I9edaae06d62e97ffdb30938d364437737238a960 Reviewed-By: Bruno Larsen --- gdb/stack.c | 4 ++++ gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/gdb/stack.c b/gdb/stack.c index 653251c200b4..4e2342c2a8d9 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1679,8 +1679,12 @@ info_frame_command_core (frame_info_ptr fi, bool selected_frame_p) else gdb_printf (" %d args: ", numargs); } + + fi.prepare_reinflate (); print_frame_args (user_frame_print_options, func, fi, numargs, gdb_stdout); + fi.reinflate (); + gdb_puts ("\n"); } } diff --git a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp index 0aeb2218f911..eb3fc9e35faf 100644 --- a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp +++ b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp @@ -98,6 +98,14 @@ with_test_prefix "frame print" { "backtrace test" } } + +# Test the "info frame" command +with_test_prefix "info frame" { + if { [start_test "TAG: first frame"] == 0 } { + gdb_test "info frame" "mytype is $hex \"hello world\".*" + } +} + # Testing the down command. with_test_prefix "frame movement down" { if { [start_test "TAG: first frame"] == 0 } { From patchwork Mon Nov 7 15:53:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60112 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D9A4B38582B4 for ; Mon, 7 Nov 2022 15:53:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D9A4B38582B4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667836438; bh=gwZ2Sa9QyhKqwVJqNqMQhUBuyooSQlPcTSp6+9+xpF8=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=onqCYjKb/V+sc5pr99GR6njUAFyN1RqB5vkW1z9KLN2bAohLj61cD/T+ikxfOpJiU qP6D/oARm4ccKXK1U/Rll0rOPNTMVuNNKAAyZBqOiK+kOLBDyeXjP/cc2I05fVLani L88BhuoL7uPtd/542I7F+X7FxY4KXYmmy12g31IU= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 6CD613858422 for ; Mon, 7 Nov 2022 15:53:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6CD613858422 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7FrBaT019846 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 10:53:16 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7FrBaT019846 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id B49ED1E124; Mon, 7 Nov 2022 10:53:11 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 3/7] gdb: move frame_info_ptr method implementations to frame-info.c Date: Mon, 7 Nov 2022 10:53:06 -0500 Message-Id: <20221107155310.2590069-3-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221107155310.2590069-1-simon.marchi@polymtl.ca> References: <20221107155310.2590069-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 15:53:11 +0000 X-Spam-Status: No, score=-3189.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" I don't see any particular reason why the implementations of the frame_info_ptr object are in the header file. It only seems to add some complexity. Since we can't include frame.h in frame-info.h, we have to add declarations of functions defined in frame.c, in frame-info.h. By moving the implementations to a new frame-info.c, we can avoid that. Change-Id: I435c828f81b8a3392c43ef018af31effddf6be9c Reviewed-By: Bruno Larsen --- gdb/Makefile.in | 1 + gdb/frame-info.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/frame-info.h | 20 ++------------------ gdb/frame.c | 4 +--- gdb/frame.h | 4 ++++ 5 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 gdb/frame-info.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index c528ee5aa806..32dbbb9c7003 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1086,6 +1086,7 @@ COMMON_SFILES = \ findvar.c \ frame.c \ frame-base.c \ + frame-info.c \ frame-unwind.c \ gcore.c \ gdb-demangle.c \ diff --git a/gdb/frame-info.c b/gdb/frame-info.c new file mode 100644 index 000000000000..84791205d906 --- /dev/null +++ b/gdb/frame-info.c @@ -0,0 +1,47 @@ +/* Frame info pointer + + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" + +#include "frame-info.h" +#include "frame.h" + +/* See frame-info-ptr.h. */ + +intrusive_list frame_info_ptr::frame_list; + +/* See frame-info-ptr.h. */ + +void +frame_info_ptr::prepare_reinflate () +{ + m_cached_id = get_frame_id (*this); +} + +/* See frame-info-ptr.h. */ + +void +frame_info_ptr::reinflate () +{ + gdb_assert (m_cached_id != null_frame_id); + + if (m_ptr == nullptr) + m_ptr = frame_find_by_id (m_cached_id).get (); + gdb_assert (m_ptr != nullptr); +} diff --git a/gdb/frame-info.h b/gdb/frame-info.h index 7159f82b1962..1d2d4bdc7e68 100644 --- a/gdb/frame-info.h +++ b/gdb/frame-info.h @@ -25,12 +25,6 @@ struct frame_info; -/* Forward declarations of functions, needed for the frame_info_ptr - to work correctly. */ -extern void reinit_frame_cache (); -extern struct frame_id get_frame_id (frame_info_ptr); -extern frame_info_ptr frame_find_by_id (struct frame_id id); - /* A wrapper for "frame_info *". frame_info objects are invalidated whenever reinit_frame_cache is called. This class arranges to invalidate the pointer when appropriate. This is done to help @@ -136,20 +130,10 @@ class frame_info_ptr : public intrusive_list_node } /* Cache the frame_id that the pointer will use to reinflate. */ - void prepare_reinflate () - { - m_cached_id = get_frame_id (*this); - } + void prepare_reinflate (); /* Use the cached frame_id to reinflate the pointer. */ - void reinflate () - { - gdb_assert (m_cached_id != null_frame_id); - - if (m_ptr == nullptr) - m_ptr = frame_find_by_id (m_cached_id).get (); - gdb_assert (m_ptr != nullptr); - } + void reinflate (); private: diff --git a/gdb/frame.c b/gdb/frame.c index 5cf9186e43d7..997fda77d019 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -19,6 +19,7 @@ #include "defs.h" #include "frame.h" +#include "frame-info.h" #include "target.h" #include "value.h" #include "inferior.h" /* for inferior_ptid */ @@ -56,9 +57,6 @@ static frame_info *sentinel_frame; /* Number of calls to reinit_frame_cache. */ static unsigned int frame_cache_generation = 0; -/* See frame-info.h. */ -intrusive_list frame_info_ptr::frame_list; - /* See frame.h. */ unsigned int diff --git a/gdb/frame.h b/gdb/frame.h index f61ea63c290b..5f7dcb69ee90 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -287,6 +287,10 @@ extern frame_info_ptr get_next_frame_sentinel_okay (frame_info_ptr); frame. */ extern frame_info_ptr get_prev_frame_always (frame_info_ptr); +/* Given a frame's ID, relocate the frame. Returns NULL if the frame + is not found. */ +extern frame_info_ptr frame_find_by_id (frame_id id); + /* Base attributes of a frame: */ /* The frame's `resume' address. Where the program will resume in From patchwork Mon Nov 7 15:53:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60113 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 961B0385828A for ; Mon, 7 Nov 2022 15:54:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 961B0385828A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667836470; bh=UkIYQVCqwRUz9I3g9lKYnEFDJ104M4Fac+nIAOmkT54=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=m8HF2a6UeNKw2FtE2kpig70IcWPs2d5p4TW3Leg2Zka4iAZXVhLf1/+SHb4K1eD1b lDsD8vLE/Zt9Ps+3HsxX1oAm2wQMd2oB89tD0LSQYYmIaEFV6pE/5LQfMJ2WUqj4H9 EwMeQ2Sn7t6DOsNdf0ssm8U7Sz0AK3fn5kq9URcg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id CB5E93858428 for ; Mon, 7 Nov 2022 15:53:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CB5E93858428 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7FrBdQ019852 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 10:53:16 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7FrBdQ019852 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id CD66C1E126; Mon, 7 Nov 2022 10:53:11 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 4/7] gdb: remove manual frame_info reinflation code in backtrace_command_1 Date: Mon, 7 Nov 2022 10:53:07 -0500 Message-Id: <20221107155310.2590069-4-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221107155310.2590069-1-simon.marchi@polymtl.ca> References: <20221107155310.2590069-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 15:53:11 +0000 X-Spam-Status: No, score=-3189.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Simon Marchi With the following patch applied (gdb: use frame_id_p instead of comparing to null_frame_id in frame_info_ptr::reinflate), I would get: $ ./gdb -q -nx --data-directory=data-directory testsuite/outputs/gdb.base/bt-selected-frame/bt-selected-frame -ex "b breakpt" -ex r -ex "bt full" Reading symbols from testsuite/outputs/gdb.base/bt-selected-frame/bt-selected-frame... Breakpoint 1 at 0x1131: file /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/bt-selected-frame.c, line 22. Starting program: /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/bt-selected-frame/bt-selected-frame [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, breakpt () at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/bt-selected-frame.c:22 22 } #0 breakpt () at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/bt-selected-frame.c:22 No locals. /home/smarchi/src/binutils-gdb/gdb/frame-info.c:42: internal-error: reinflate: Assertion `frame_id_p (m_cached_id)' failed. This is because the code in backtrace_command_1 to manually reinflate `fi` steps overs frame_info_ptr's toes. When calling fi.prepare_reinflate (); `fi` gets properly filled with the cached frame id. But when this happens: fi = frame_find_by_id (frame_id); `fi` gets replaced by a brand new frame_info_ptr that doesn't have a cached frame id. Then this is called without a cached frame id: fi.reinflate (); That doesn't cause any problem currently, since - the gdb_assert in the reinflate method doesn't actually do anything (the following patch fixes that) - `fi.m_ptr` will always be non-nullptr, since we just got it from frame_find_by_id, so reinflate will not do anything, it won't try to use m_cached_id Fix that by removing the code to manually re-fetch the frame. That should be taken care of by frame_info_ptr::reinflate. Note that the old code checked if we successfully re-inflated the frame or not, and if not it did emit a warning. The equivalent in frame_info_ptr::reinflate asserts that the frame has been successfully re-inflated. It's not clear if / when this can happen, but if it can happen, we'll need to find a solution to this problem globally (everywhere a frame_info_ptr can be re-inflated), not just here. So I propose to leave it like this, until it does become a problem. Change-Id: I07b783d94e2853e0a2d058fe7deaf04eddf24835 --- gdb/stack.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/gdb/stack.c b/gdb/stack.c index 4e2342c2a8d9..5f29566fcfe9 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -2082,20 +2082,7 @@ backtrace_command_1 (const frame_print_options &fp_opts, print_frame_info (fp_opts, fi, 1, LOCATION, 1, 0); if ((flags & PRINT_LOCALS) != 0) - { - struct frame_id frame_id = get_frame_id (fi); - - print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout); - - /* print_frame_local_vars invalidates FI. */ - fi = frame_find_by_id (frame_id); - if (fi == NULL) - { - trailing = NULL; - warning (_("Unable to restore previously selected frame.")); - break; - } - } + print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout); /* Save the last frame to check for error conditions. */ fi.reinflate (); From patchwork Mon Nov 7 15:53:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60115 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0BA6D3858415 for ; Mon, 7 Nov 2022 16:03:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0BA6D3858415 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667836983; bh=pEUDWb6Pbu8YoOtcC97T68xVU5rk68FSNWjfzaLPGqo=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=JkIfKqqg/VyBCKWpPdEyxC7OWr338cbBYPK1kCfo1ETsSr8sCtYjVQNERfSwr/kHW O/2INIj8tZyJPW7PwSBNyzOtU4+L4FRne04pK9QjGNR2U/tKWmaZDEdf0lcHmwlPYd BSlz+SkOQsxyZBxbmChWubnGVnCg9S1Vi6g76Ylg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id A33C13858C39 for ; Mon, 7 Nov 2022 16:02:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A33C13858C39 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7G2CHq028379 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 11:02:17 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7G2CHq028379 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id 1E1EE1E128; Mon, 7 Nov 2022 10:53:11 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 5/7] gdb: use frame_id_p instead of comparing to null_frame_id in frame_info_ptr::reinflate Date: Mon, 7 Nov 2022 10:53:08 -0500 Message-Id: <20221107155310.2590069-5-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221107155310.2590069-1-simon.marchi@polymtl.ca> References: <20221107155310.2590069-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 16:02:12 +0000 X-Spam-Status: No, score=-3189.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Simon Marchi The assertion gdb_assert (m_cached_id != null_frame_id); is always true, as comparing equal to null_frame_id is always false (it's the first case in frame_id::operator==, not sure why it's not this way, but that's what it is). Replace the comparison with a call to frame_id_p. Change-Id: I93986e6a85ac56353690792552e5b3b4cedec7fb --- gdb/frame-info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdb/frame-info.c b/gdb/frame-info.c index 84791205d906..584222dc490f 100644 --- a/gdb/frame-info.c +++ b/gdb/frame-info.c @@ -39,7 +39,7 @@ frame_info_ptr::prepare_reinflate () void frame_info_ptr::reinflate () { - gdb_assert (m_cached_id != null_frame_id); + gdb_assert (frame_id_p (m_cached_id)); if (m_ptr == nullptr) m_ptr = frame_find_by_id (m_cached_id).get (); From patchwork Mon Nov 7 15:53:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60116 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0C4BF385841E for ; Mon, 7 Nov 2022 16:03:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0C4BF385841E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667836983; bh=QZCtB6Y2wJflJJwIlMc2nOYrSx4IhOFBBw43yAk5Xjk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=I8ge2BdwObhuLJxtSwl9xYqjZybpiThxDLKEnyuLOZLQeARWjBedhNtyJ84OSp3Ru BENNP4oPAttGAnUoy0Xz47izW9MvedlcquTxQXjnKC7mm5wdevRMjgqk7hqhn/A1eN +pxQi7QFtkEoVK1qJy6WbNlu6v7MIazoLZBp5Qbg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 28F163858C33 for ; Mon, 7 Nov 2022 16:02:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 28F163858C33 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7G2CMU028380 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 11:02:17 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7G2CMU028380 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id 463591E129; Mon, 7 Nov 2022 10:53:12 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 6/7] gdb: add missing prepare_reinflate call in print_frame_info Date: Mon, 7 Nov 2022 10:53:09 -0500 Message-Id: <20221107155310.2590069-6-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221107155310.2590069-1-simon.marchi@polymtl.ca> References: <20221107155310.2590069-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 16:02:12 +0000 X-Spam-Status: No, score=-3189.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" print_frame_info calls frame_info_ptr::reinflate, but not frame_info_ptr::prepare_reinflate, add the call to reinflate. It works right now, because all callers of print_frame_info that could possibly lead to the pretty printers being called, and the frame_info objects being invalidated, do call prepare_reinflate themselves. And since the cached frame id is copied when passing a frame_info_ptr by value, print_frame_info does have a cached frame id on entry. So technically, this change isn't needed. But I don't think it's good for a function to rely on its callers to have called prepare_reinflate, if it intends to call reinflate. Change-Id: Ie332b2d5479aef46f83fdc1120c7c83f4e84d1b0 Reviewed-By: Bruno Larsen --- gdb/stack.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gdb/stack.c b/gdb/stack.c index 5f29566fcfe9..4ad51c2eb50e 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1047,6 +1047,8 @@ print_frame_info (const frame_print_options &fp_opts, int location_print; struct ui_out *uiout = current_uiout; + frame.prepare_reinflate (); + if (!current_uiout->is_mi_like_p () && fp_opts.print_frame_info != print_frame_info_auto) { From patchwork Mon Nov 7 15:53:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 60117 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 684FC3858422 for ; Mon, 7 Nov 2022 16:03:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 684FC3858422 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667837015; bh=IeGyOgrXj/biJ+O7cm0IP8dWpzYr1UqFhcus5M/hJJA=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Gapo9xO3ZS2P7S7iZ8XQk7oYNo2gIOUyGU1MmbgfuOROd0edcGH5Ubh7YtWS9miiQ MX0NDT0PkrKOFZ/vCjM/X8wF2WOiyw9BQfIdHLpb/wmwWP0O37AM8YtLTrd6dDc0C8 5EMe8sS0Tn/77+itskGNp5UZWXhx1z78U6jHQ4GI= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 2E08C3858417 for ; Mon, 7 Nov 2022 16:02:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2E08C3858417 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2A7G2CUU028390 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 7 Nov 2022 11:02:17 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2A7G2CUU028390 Received: from simark.localdomain (unknown [217.28.27.60]) (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 ESMTPSA id 732501E12A; Mon, 7 Nov 2022 10:53:12 -0500 (EST) To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 7/7] gdb: add special handling for frame level 0 in frame_info_ptr Date: Mon, 7 Nov 2022 10:53:10 -0500 Message-Id: <20221107155310.2590069-7-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221107155310.2590069-1-simon.marchi@polymtl.ca> References: <20221107155310.2590069-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 7 Nov 2022 16:02:12 +0000 X-Spam-Status: No, score=-3189.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Simon Marchi I noticed this problem while preparing the initial submission for the ROCm GDB port. One particularity of this patch set is that it does not support unwinding frames, that requires support of some DWARF extensions that will come later. It was still possible to run to a breakpoint and print frame #0, though. When rebasing on top of the frame_info_ptr work, GDB started tripping on a prepare_reinflate call, making it not possible anymore to event print the frame when stopping on a breakpoint. One thing to know about frame 0 is that its id is lazily computed when something requests it through get_frame_id. See: https://gitlab.com/gnutools/binutils-gdb/-/blob/23912acd402f5af9caf91b257e5209ec4c58a09c/gdb/frame.c#L2070-2080 So, up to that prepare_reinflate call, frame 0's id was not computed, and prepare_reinflate, calling get_frame_id, forces it to be computed. Computing the frame id generally requires unwinding the previous frame, which with my ROCm GDB patch fails. An exception is thrown and the printing of the frame is simply abandonned. Regardless of this ROCm GDB problem (which is admittedly temporary, it will be possible to unwind with subsequent patches), we want to avoid prepare_reinflate to force the computing of the frame id, for the same reasons we lazily compute it in the first place. In addition, frame 0's id is subject to change across a frame cache reset. This is why save_selected_frame and restore_selected_frame have special handling for frame 0: https://gitlab.com/gnutools/binutils-gdb/-/blob/23912acd402f5af9caf91b257e5209ec4c58a09c/gdb/frame.c#L1841-1863 For this last reason, we also need to handle frame 0 specially in prepare_reinflate / reinflate. Because the frame id of frame 0 can change across a frame cache reset, we must not rely on the frame id from that frame to reinflate it. We should instead just re-fetch the current frame at that point. This patch adds a frame_info_ptr::m_cached_level field, set in frame_info_ptr::prepare_reinflate, so we can tell if a frame is frame 0. There are cases where a frame_info_ptr object wraps a sentinel frame, for which frame_relative_level returns -1, so I have chosen the value -2 to represent "invalid frame level", for when the frame_info_ptr object is empty. In frame_info_ptr::prepare_reinflate, only cache the frame id if the frame level is not 0. It's fine to cache the frame id for the sentinel frame, it will be properly handled by frame_find_by_id later. In frame_info_ptr::reinflate, if the frame level is 0, call get_current_frame to get the target's current frame. Otherwise, use frame_find_by_id just as before. This patch should not have user-visible changes with upstream GDB. But it will avoid forcing the computation of frame 0's when calling prepare_reinflate. And, well, it fixes the upcoming ROCm GDB patch series. Change-Id: I176ed7ee9317ddbb190acee8366e087e08e4d266 Reviewed-By: Bruno Larsen Reviewed-By: Bruno Larsen --- gdb/frame-info.c | 24 ++++++++++++++++++++---- gdb/frame-info.h | 20 ++++++++++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/gdb/frame-info.c b/gdb/frame-info.c index 584222dc490f..e3ee9f8174e1 100644 --- a/gdb/frame-info.c +++ b/gdb/frame-info.c @@ -31,7 +31,11 @@ intrusive_list frame_info_ptr::frame_list; void frame_info_ptr::prepare_reinflate () { - m_cached_id = get_frame_id (*this); + m_cached_level = frame_relative_level (*this); + gdb_assert (m_cached_level >= -1); + + if (m_cached_level != 0) + m_cached_id = get_frame_id (*this); } /* See frame-info-ptr.h. */ @@ -39,9 +43,21 @@ frame_info_ptr::prepare_reinflate () void frame_info_ptr::reinflate () { - gdb_assert (frame_id_p (m_cached_id)); + gdb_assert (m_cached_level >= -1); + + if (m_ptr != nullptr) + { + /* The frame_info wasn't invalidated, no need to reinflate. */ + return; + } + + if (m_cached_level == 0) + m_ptr = get_current_frame ().get (); + else + { + gdb_assert (frame_id_p (m_cached_id)); + m_ptr = frame_find_by_id (m_cached_id).get (); + } - if (m_ptr == nullptr) - m_ptr = frame_find_by_id (m_cached_id).get (); gdb_assert (m_ptr != nullptr); } diff --git a/gdb/frame-info.h b/gdb/frame-info.h index 1d2d4bdc7e68..3369b114326f 100644 --- a/gdb/frame-info.h +++ b/gdb/frame-info.h @@ -56,16 +56,21 @@ class frame_info_ptr : public intrusive_list_node } frame_info_ptr (const frame_info_ptr &other) - : m_ptr (other.m_ptr), m_cached_id (other.m_cached_id) + : m_ptr (other.m_ptr), + m_cached_id (other.m_cached_id), + m_cached_level (other.m_cached_level) { frame_list.push_back (*this); } frame_info_ptr (frame_info_ptr &&other) - : m_ptr (other.m_ptr), m_cached_id (other.m_cached_id) + : m_ptr (other.m_ptr), + m_cached_id (other.m_cached_id), + m_cached_level (other.m_cached_level) { other.m_ptr = nullptr; other.m_cached_id = null_frame_id; + other.m_cached_level = invalid_level; frame_list.push_back (*this); } @@ -78,6 +83,7 @@ class frame_info_ptr : public intrusive_list_node { m_ptr = other.m_ptr; m_cached_id = other.m_cached_id; + m_cached_level = other.m_cached_level; return *this; } @@ -85,6 +91,7 @@ class frame_info_ptr : public intrusive_list_node { m_ptr = nullptr; m_cached_id = null_frame_id; + m_cached_level = invalid_level; return *this; } @@ -92,8 +99,10 @@ class frame_info_ptr : public intrusive_list_node { m_ptr = other.m_ptr; m_cached_id = other.m_cached_id; + m_cached_level = other.m_cached_level; other.m_ptr = nullptr; other.m_cached_id = null_frame_id; + other.m_cached_level = invalid_level; return *this; } @@ -136,6 +145,10 @@ class frame_info_ptr : public intrusive_list_node void reinflate (); private: + /* We sometimes need to construct frame_info_ptr objects around the + sentinel_frame, which has level -1. Therefore, make the invalid frame + level value -2. */ + static constexpr int invalid_level = -2; /* The underlying pointer. */ frame_info *m_ptr = nullptr; @@ -143,6 +156,9 @@ class frame_info_ptr : public intrusive_list_node /* The frame_id of the underlying pointer. */ frame_id m_cached_id = null_frame_id; + /* The frame level of the underlying pointer. */ + int m_cached_level = invalid_level; + /* All frame_info_ptr objects are kept on an intrusive list. This keeps their construction and destruction costs reasonably small. */