Message ID | 1fcffbf8ffd62b07585baebff38b66f10ec0a112.1677582745.git.tankut.baris.aktemur@intel.com |
---|---|
State | New |
Headers |
Return-Path: <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> 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 895F83848435 for <patchwork@sourceware.org>; Tue, 28 Feb 2023 11:31:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 895F83848435 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677583884; bh=7V/5xAd4XFNukQAAHSqw7a2TBzM2Os1ze5URejpmePo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=eYkjiJ/kJOpT63XAFQx5J5N76sKBr9XIFZMgOZE/Eg63saANqbI/c164m5qA+xIRF XupsKN4vsfI9uu1s37qKxLs4mZKD9P99qMqspgfRFTaULyS+yqr5cSYmXeyyHXBCoV Z2WpeCeU9c5Skcr6pjSc5TWi1vdaLkeQEBGPcB7g= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by sourceware.org (Postfix) with ESMTPS id 81467384D16E for <gdb-patches@sourceware.org>; Tue, 28 Feb 2023 11:30:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 81467384D16E X-IronPort-AV: E=McAfee;i="6500,9779,10634"; a="313785189" X-IronPort-AV: E=Sophos;i="5.98,221,1673942400"; d="scan'208";a="313785189" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Feb 2023 03:30:59 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10634"; a="623992239" X-IronPort-AV: E=Sophos;i="5.98,221,1673942400"; d="scan'208";a="623992239" Received: from ultl2604.iul.intel.com (HELO localhost) ([172.28.48.47]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Feb 2023 03:30:58 -0800 To: gdb-patches@sourceware.org Subject: [PATCH 21/26] gdbserver: use REG_UNKNOWN for a regcache's register statuses Date: Tue, 28 Feb 2023 12:28:19 +0100 Message-Id: <1fcffbf8ffd62b07585baebff38b66f10ec0a112.1677582745.git.tankut.baris.aktemur@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <cover.1677582744.git.tankut.baris.aktemur@intel.com> References: <cover.1677582744.git.tankut.baris.aktemur@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_PASS, SPF_NONE, 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 <gdb-patches.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=subscribe> From: Tankut Baris Aktemur via Gdb-patches <gdb-patches@sourceware.org> Reply-To: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> |
Series |
gdbserver: refactor regcache and allow gradually populating
|
|
Commit Message
Aktemur, Tankut Baris
Feb. 28, 2023, 11:28 a.m. UTC
When a regcache is initialized, the values of registers are not fetched yet. Thus, initialize the register statuses to REG_UNKNOWN instead of REG_UNAVAILABLE, because the latter rather means "we attempted to fetch but could not obtain the value". The definitions of the reg status enums (from gdbsupport/common-regcache.h) as a reminder: /* The register value is not in the cache, and we don't know yet whether it's available in the target (or traceframe). */ REG_UNKNOWN = 0, /* The register value is valid and cached. */ REG_VALID = 1, /* The register value is unavailable. E.g., we're inspecting a traceframe, and this register wasn't collected. Note that this "unavailable" is different from saying the register does not exist in the target's architecture --- in that case, the target should have given us a target description that does not include the register in the first place. */ REG_UNAVAILABLE = -1 Similarly, when the regcache is invalidated, change all the statuses back to REG_UNKNOWN. --- gdbserver/regcache.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
Comments
On 2023-02-28 06:28, Tankut Baris Aktemur via Gdb-patches wrote: > When a regcache is initialized, the values of registers are not > fetched yet. Thus, initialize the register statuses to REG_UNKNOWN > instead of REG_UNAVAILABLE, because the latter rather means "we > attempted to fetch but could not obtain the value". > > The definitions of the reg status enums (from > gdbsupport/common-regcache.h) as a reminder: > > /* The register value is not in the cache, and we don't know yet > whether it's available in the target (or traceframe). */ > REG_UNKNOWN = 0, > > /* The register value is valid and cached. */ > REG_VALID = 1, > > /* The register value is unavailable. E.g., we're inspecting a > traceframe, and this register wasn't collected. Note that this > "unavailable" is different from saying the register does not > exist in the target's architecture --- in that case, the target > should have given us a target description that does not include > the register in the first place. */ > REG_UNAVAILABLE = -1 > > Similarly, when the regcache is invalidated, change all the statuses > back to REG_UNKNOWN. That makes sense to me. > --- > gdbserver/regcache.cc | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc > index 09ea58bdbd6..2befb30e337 100644 > --- a/gdbserver/regcache.cc > +++ b/gdbserver/regcache.cc > @@ -64,9 +64,17 @@ regcache::fetch () > switch_to_thread (this->thread); > > /* Invalidate all registers, to prevent stale left-overs. */ > - memset (register_status, REG_UNAVAILABLE, tdesc->reg_defs.size ()); > + discard (); > fetch_inferior_registers (this, -1); > registers_fetched = true; > + > + /* Make sure that the registers that could not be fetched are > + now unavailable. */ > + for (int i = 0; i < tdesc->reg_defs.size (); ++i) > + { > + if (register_status[i] == REG_UNKNOWN) > + set_register_status (i, REG_UNAVAILABLE); > + } The braces are not needed. But is it really needed to do this? Unavailable is only meaningful for tracing, in a regcache that is the result of tracepoint collection. For a regcache created by reading registers from the target, I don't think that setting statuses to unavailable makes sense. Also, if asking the target to fetch all registers, why would some registers still be unknown? It's the target that provides the target description, it's supposed to only include registers that exist (like the comment on top of REG_UNAVAILABLE says). So it should be able to read them all. In other words, I think this loop should be asserting that all statuses are REG_VALID. But then for the tracing case, I wonder who sets the statuses to REG_UNAVAILABLE for those statuses that should really be REG_UNAVAILABLE. From what I can see, all regcaches used on the tracing code paths use the regcache constructor with 2 arguments, which means regcaches that don't track the status of registers (regcache::register_status is nullptr). So... now that you changed regcache to use REG_UNKNOWN by default, is REG_UNAVAILABLE really used in GDBserver? I noticed that do_action_at_tracepoint has a comment that says "Collect all registers for now.". I guess that if it didn't collect all registers, this would be a spot that would explicitly set some registers to REG_UNAVAILABLE. I see that for fast tracepoints, for instance supply_fast_tracepoint_registers in linux-amd64-ipa.cc, we supply a fixed set of registers. Clearly, these are not all the registers that an amd64 machine could have. But it just writes a register buffer that ends up in the trace, there doesn't seem to be a way to communicate which registers were collected and which weren't. When we create a new regcache to read these registers, when handling the 'g' packet in server.cc, there's no way to know which individual registers were collected and which weren't. Simon
diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc index 09ea58bdbd6..2befb30e337 100644 --- a/gdbserver/regcache.cc +++ b/gdbserver/regcache.cc @@ -64,9 +64,17 @@ regcache::fetch () switch_to_thread (this->thread); /* Invalidate all registers, to prevent stale left-overs. */ - memset (register_status, REG_UNAVAILABLE, tdesc->reg_defs.size ()); + discard (); fetch_inferior_registers (this, -1); registers_fetched = true; + + /* Make sure that the registers that could not be fetched are + now unavailable. */ + for (int i = 0; i < tdesc->reg_defs.size (); ++i) + { + if (register_status[i] == REG_UNKNOWN) + set_register_status (i, REG_UNAVAILABLE); + } } } @@ -128,6 +136,9 @@ regcache_invalidate (void) void regcache::discard () { +#ifndef IN_PROCESS_AGENT + memset ((void *) register_status, REG_UNKNOWN, tdesc->reg_defs.size ()); +#endif registers_fetched = false; } @@ -148,8 +159,7 @@ regcache::initialize (const target_desc *tdesc, this->registers_owned = true; this->register_status = (enum register_status *) xmalloc (tdesc->reg_defs.size ()); - memset ((void *) this->register_status, REG_UNAVAILABLE, - tdesc->reg_defs.size ()); + discard (); #else gdb_assert_not_reached ("can't allocate memory from the heap"); #endif