From patchwork Mon Oct 2 18:36:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 76981 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 C1CCC3858C62 for ; Mon, 2 Oct 2023 18:36:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C1CCC3858C62 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1696271808; bh=i+Hl8d1zL5FOEY97MaK0AVQ3qsF6kIRqcobosXcNRyc=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=SH4mAhD/rAx6DlRlKTKDq3+jeVVoOLGfl4GbvleVB24iGoHwK905pn0mfE2EpU3UX pJ6J7g9qpG8X67QQD8FjUYGJP8VZvsZ9v8sQiroZ99ehUfT6aDHpeQJwdQi1A6gye2 N8CvJo8QGhoMmXNeagoLQZalPt8aOWNweB3Mj/nM= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x129.google.com (mail-il1-x129.google.com [IPv6:2607:f8b0:4864:20::129]) by sourceware.org (Postfix) with ESMTPS id 4C42D3858D32 for ; Mon, 2 Oct 2023 18:36:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4C42D3858D32 Received: by mail-il1-x129.google.com with SMTP id e9e14a558f8ab-351365e47f6so168635ab.1 for ; Mon, 02 Oct 2023 11:36:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696271782; x=1696876582; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=i+Hl8d1zL5FOEY97MaK0AVQ3qsF6kIRqcobosXcNRyc=; b=Whzi0+N+KJPi2i42gavaMJnL9EPsYoZvSuHfU0X6kTwsnHY1M3YGqXx3nwcZlpDc8U o81se5ZQYGa1b8Nv3P1IbetVjYBOqO5kenLcXg/3txgdmRcjUoNCc7Ul4Tz1rpAb0Dco ihWsOEH/DfF49lem3wP0vc0C8jSaV5LFFwRPU9bil3wwP8fSAiGGjjrRdbYLIPVN/gjg NAcWLTbFl0rKNWPJcUSAjQ2Y+EZ2wF5QqS+TnHtsA4yk0ywLw0QxmMF9WpcPFyuz4WkW jQQoPBTyx0V6b+H2t4B+UwKrq5Bp47SoF02dd4RsN1GbD5r5Ge4zH5y9oo8IxS1CKF3o uN6A== X-Gm-Message-State: AOJu0YxxTv99mLxdZyA9vjrRQDOsDKXz3AGh9m6kXH1baLYHJHFgTjHj qnxL+SSEeDm1C617cgbzaGrtqpqm+NsO6tniaQvnxQ== X-Google-Smtp-Source: AGHT+IHBAtKTSx0Ub1sSH2CQQ48OtQZgiIu1Tdl4FeXjUXAYyvfoT8ZjT1aickNXbD1KMjjL99nxhQ== X-Received: by 2002:a05:6e02:ec3:b0:350:f352:4853 with SMTP id i3-20020a056e020ec300b00350f3524853mr11245876ilk.25.1696271782477; Mon, 02 Oct 2023 11:36:22 -0700 (PDT) Received: from localhost.localdomain (71-211-130-31.hlrn.qwest.net. [71.211.130.31]) by smtp.gmail.com with ESMTPSA id y19-20020a056e02119300b003513e84e707sm5605754ili.30.2023.10.02.11.36.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Oct 2023 11:36:22 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Add DAP scope cache Date: Mon, 2 Oct 2023 12:36:15 -0600 Message-Id: <20231002183615.161787-1-tromey@adacore.com> X-Mailer: git-send-email 2.40.1 MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Andry Ogorodnik, a co-worker, noticed that multiple "scopes" requests with the same frame would yield different variableReference values in the response. This patch adds a regression test for this, and adds a scope cache in scopes.py, ensuring that multiple identical requests will get the same response. --- gdb/python/lib/gdb/dap/scopes.py | 38 ++++++++++++++++++++++++-------- gdb/testsuite/gdb.dap/scopes.exp | 7 ++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/gdb/python/lib/gdb/dap/scopes.py b/gdb/python/lib/gdb/dap/scopes.py index 4874d001216..5dde060f44f 100644 --- a/gdb/python/lib/gdb/dap/scopes.py +++ b/gdb/python/lib/gdb/dap/scopes.py @@ -21,6 +21,21 @@ from .server import request from .varref import BaseReference +# Map DAP frame IDs to scopes. This ensures that scopes are re-used. +frame_to_scope = {} + + +# When the inferior is re-started, we erase all scope references. See +# the section "Lifetime of Objects References" in the spec. +@in_gdb_thread +def clear_scopes(event): + global frame_to_scope + frame_to_scope = {} + + +gdb.events.cont.connect(clear_scopes) + + class _ScopeReference(BaseReference): def __init__(self, name, hint, frame, var_list): super().__init__(name) @@ -83,15 +98,20 @@ class _RegisterReference(_ScopeReference): # Helper function to create a DAP scopes for a given frame ID. @in_gdb_thread def _get_scope(id): - frame = frame_for_id(id) - scopes = [] - args = frame.frame_args() - if args: - scopes.append(_ScopeReference("Arguments", "arguments", frame, args)) - locs = frame.frame_locals() - if locs: - scopes.append(_ScopeReference("Locals", "locals", frame, locs)) - scopes.append(_RegisterReference("Registers", frame)) + global frame_to_scope + if id in frame_to_scope: + scopes = frame_to_scope[id] + else: + frame = frame_for_id(id) + scopes = [] + args = frame.frame_args() + if args: + scopes.append(_ScopeReference("Arguments", "arguments", frame, args)) + locs = frame.frame_locals() + if locs: + scopes.append(_ScopeReference("Locals", "locals", frame, locs)) + scopes.append(_RegisterReference("Registers", frame)) + frame_to_scope[id] = scopes return [x.to_object() for x in scopes] diff --git a/gdb/testsuite/gdb.dap/scopes.exp b/gdb/testsuite/gdb.dap/scopes.exp index 6937badcca0..003557cf323 100644 --- a/gdb/testsuite/gdb.dap/scopes.exp +++ b/gdb/testsuite/gdb.dap/scopes.exp @@ -52,6 +52,13 @@ set scopes [dap_check_request_and_response "get scopes" scopes \ [format {o frameId [i %d]} $frame_id]] set scopes [dict get [lindex $scopes 0] body scopes] +# Request the scopes twice, and verify that the results are identical. +# GDB previously had a bug where it would return new scopes each time. +set scopes2 [dap_check_request_and_response "get scopes again" scopes \ + [format {o frameId [i %d]} $frame_id]] +set scopes2 [dict get [lindex $scopes2 0] body scopes] +gdb_assert {$scopes2 == $scopes} "identical scopes requests yield same body" + gdb_assert {[llength $scopes] == 2} "two scopes" lassign $scopes scope reg_scope