From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id ifpSKAeoyGjX+AUAWB0awg (envelope-from ) for ; Mon, 15 Sep 2025 19:57:59 -0400 Received: by simark.ca (Postfix, from userid 112) id 895761E047; Mon, 15 Sep 2025 19:57:59 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.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 ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 4310B1E047 for ; Mon, 15 Sep 2025 19:57:58 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 739B03858CD1 for ; Mon, 15 Sep 2025 23:57:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 739B03858CD1 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) by sourceware.org (Postfix) with ESMTPS id A7E523858D1E for ; Mon, 15 Sep 2025 23:57:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A7E523858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A7E523858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757980638; cv=none; b=NckEd8y178493wI7erWSAiQB7bkFrTE+kdCgXT8yz0H8fVUqVKkNnz1nQPoij25kEYk8k20yKZXOu2fygTN2dsm4nVxSodKZLSfQSz3SVMLiFUbD+q3qdbX9awCBK8a0sAad/eqgwE4ntDzC8ZO4sugnqgKvu4LBhUuziYh76LM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757980638; c=relaxed/simple; bh=pV9wDzoyrUq8Kj9NkkF79fxePfdgWjDV5bg0P8qiS5o=; h=Message-ID:Date:MIME-Version:Subject:From:To; b=r1X3t9G8SYIAsM3F9guE/u4IEoQDESPUbp+k2z+rkHPGbBxw2Y3vsX+Bj0a7ic2KXwKklTqqqnS8VWFEjOYfziV5upuGMoKwz6LMS7vP+VGFZe49UutnjWiGsbrNiE2apeYAmevZyiTBTTOyUgsZzJwcpb+5bvkXcomfzvJB2os= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A7E523858D1E Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-45f2c9799a3so11072045e9.0 for ; Mon, 15 Sep 2025 16:57:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757980637; x=1758585437; h=content-transfer-encoding:in-reply-to:content-language:references :to:from:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FcA0mzxZ2xt6wW4prps2E6prNvgThSvM/U1B2X3XkeY=; b=S1FS6xfPSCcBCYsnsAN4XvmpP8oXIOmLM0s3+9DWlHb0Xbe2rFq7gyfOQ69RrE3dLO m9xMmvxZkfW46UwenW91QO0wuaakX/Sd89NOqynk55hyTSvDFmWyLLMarUHzIMQ4C7XW EwBGwnEIA38aB8AZsYh741IusisOn8I993FJpN7me17pVosK32/dMXQixo5rbUuIi87z LNq7RM84zLKP9uwo/eoy4bCcmQJsILrwz6S28CAAsKIhs3o8uUbT2Q9LxUwt2UazvlWj 30iL0U/A6pGa0o88pm03aBvB1MpSYh2wqxaOiZZTJA8XPv2wS+23hr8pUYdNjPNMU/ld VjRw== X-Gm-Message-State: AOJu0YwEQHpSlYBu5001c7TcKATyyQj+FIvui3OdBHnu2aC6YJcQ2DpK UaF3Bvqnf6cZysxmdkAo/ln742I4ezM+CLl9xIqEs3Brx/Vjx6zIr1YF0Y9yr2qa X-Gm-Gg: ASbGncspGXhbzSB0dmjFsbt5C+8xwsxsxtvZoYDPg+p3q+uGxF5ki6mYWSoVFAq91fc cmXcHKVjfAvGYchIAY7gtJj7ZKWv+1Y3cpy7i251PcqkLN3Okfo88Ix5+ZYCZH51VRxJShYH+HE DC1vDbSNb13X6YJpxcaU6mnJWycedK3AgeIrxPepQ6GB9fPuGtKlZdHRj1GAT3MhxeKFoWDHmZj 9q8z9QLI4ut7OppjIA1sdOCIElKU1kAGp91gh7v88Y3Xn3O2p84/YF3HXMSk3ZBHTc7YzxJzTq+ WeSdF1iJsYBqtbH9V+sgCFYHWbcjBJfKP/sAq2zf5MqVwMNjXXNVIyAhSpKLk7IkTm6jTTFvRQs Luuvna5KcMQMELwOuYBKAU0R7hxyH+hgo99JXSExX2zcOd8Wycye9EWFN2sIBXlQ= X-Google-Smtp-Source: AGHT+IGcE7qwB9a4oOyS/OIC+a964LMQd25BdzrPCFP9W9ubi/th5iYkpC85eJg6LthITLMVa3l1zg== X-Received: by 2002:a05:600c:3651:b0:45c:b53f:ad9 with SMTP id 5b1f17b1804b1-45f21201ec8mr97212115e9.33.1757980636978; Mon, 15 Sep 2025 16:57:16 -0700 (PDT) Received: from ?IPV6:2001:8a0:fad8:400:9f0e:9939:cce1:9ecb? ([2001:8a0:fad8:400:9f0e:9939:cce1:9ecb]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3e760775880sm19747435f8f.2.2025.09.15.16.57.15 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 15 Sep 2025 16:57:15 -0700 (PDT) Message-ID: Date: Tue, 16 Sep 2025 00:57:11 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH] Make gdb_caching_proc support namespaces From: Pedro Alves To: gdb-patches@sourceware.org References: <20250915212841.4161603-1-pedro@palves.net> <3e29d575-22c4-42b7-a8e9-2d57b7367a49@palves.net> Content-Language: en-US In-Reply-To: <3e29d575-22c4-42b7-a8e9-2d57b7367a49@palves.net> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org On 2025-09-15 22:54, Pedro Alves wrote: > I should have mentioned something here: > > On 2025-09-15 22:28, Pedro Alves wrote: > >> --- a/gdb/testsuite/lib/cache.exp >> +++ b/gdb/testsuite/lib/cache.exp >> @@ -24,26 +24,9 @@ proc ignore_pass { msg } { >> >> # Call proc real_name and return the result, while ignoring calls to pass. >> proc gdb_do_cache_wrap {real_name args} { >> - if { [info procs save_pass] != "" } { >> - return [uplevel 2 $real_name] >> + with_override pass ignore_pass { >> + return [$real_name {*}$args] >> } > > The previous code was using "uplevel 2" here. But I'm struggling to see why that is the > right level. > > When gdb_do_cache_wrap is called via gdb_caching_proc => gdb_do_cache, that takes us to the scope of > the caller of the gdb_caching_proc, which off hand would seem right. > > However, when gdb_do_cache_wrap is called directly by gdb.testsuite/gdb-caching-proc-consistency.exp, it > takes us to ... the caller of test_proc? > > So I'm wondering, what could we possibly want to reference from a higher level in gdb_do_cache_wrap > that not having the uplevel in gdb_do_cache_wrap would get wrong? A caching proc IMO shouldn't be doing > something like taking the name of a variable as argument instead of a value, as then the procedure wouldn't > be guaranteed to be idempotent? So I dropped the uplevel, and found that that doesn't cause any > testsuite regression. But maybe I'm missing something. If I am, it'd be nice to add a testcase for it. Trying to find a testcase for the above, I thought to try a gdb_caching_proc defined in a namespace, and have that proc access a namespace variable, in its own namespace. That ran into the fact that gdb_caching_proc doesn't support namespaces today. So I fixed that, with the patch below (on top of the previous one), which includes tests. That still didn't require any uplevel in gdb_do_cache_wrap. I don't have a current use for this, but I figure that eventually we will find a use, and since I wrote it... == 8< === >From e9bad21e186f6024cbbecc97b4b0f593bc8ed7ea Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 16 Sep 2025 00:41:30 +0100 Subject: [PATCH] Make gdb_caching_proc support namespaces Currently, defining a gdb_caching_proc in a namespace, like: namespace eval myns { gdb_caching_proc nsproc {} { return 1 } } Incorrectly defines the advertised procedure in the global namespace instead of in the namespace of the procedure being wrapped. I.e., for the example above, calling myns::nsproc would fail, and calling "::nsproc" would succeed. This patch fixes it, and adds tests to gdb.testsuite/gdb-caching-proc.exp. Change-Id: I1853f9f411406331eb44d53d028d65a3d400db7f --- .../gdb.testsuite/gdb-caching-proc.exp | 39 ++++++++++---- gdb/testsuite/lib/cache.exp | 54 ++++++++++++------- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp b/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp index 6b46b1c555a..8b5168e5394 100644 --- a/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp +++ b/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp @@ -27,27 +27,46 @@ gdb_caching_proc gdb_testsuite_gdb_caching_proc_exp_arg_nested { arg } { return [gdb_testsuite_gdb_caching_proc_exp_arg $arg] } -# List of "expected $::count after running expression" and +namespace eval myns { + variable ns_count 1 + + gdb_caching_proc nsproc {} { + variable ns_count + incr ns_count + return 1 + } +} + +gdb_caching_proc ::fq_proc {} { + incr ::count + return 1 +} + +# List of "VAR, expected value of VAR after running expression", and # "expression". set assertions { - 1 { [gdb_testsuite_gdb_caching_proc_exp_noarg] == 1 } - 1 { [gdb_testsuite_gdb_caching_proc_exp_arg 1] == 1 } - 1 { [gdb_testsuite_gdb_caching_proc_exp_arg "foo foo"] == "foo foo" } - 1 { [gdb_testsuite_gdb_caching_proc_exp_arg_nested "foo foo"] == "foo foo" } - 2 { [gdb_testsuite_gdb_caching_proc_exp_arg_nested "bar bar"] == "bar bar" } + count 2 { [gdb_testsuite_gdb_caching_proc_exp_noarg] == 1 } + count 2 { [gdb_testsuite_gdb_caching_proc_exp_arg 1] == 1 } + count 2 { [gdb_testsuite_gdb_caching_proc_exp_arg "foo foo"] == "foo foo" } + count 2 { [gdb_testsuite_gdb_caching_proc_exp_arg_nested "foo foo"] == "foo foo" } + count 3 { [gdb_testsuite_gdb_caching_proc_exp_arg_nested "bar bar"] == "bar bar" } + count 2 { [fq_proc] == 1 } + myns::ns_count 2 { [myns::nsproc] == 1 } } set assertion_nr 0 -foreach {expected_count assertion} $assertions { +foreach {var expected_var_value assertion} $assertions { with_test_prefix $assertion_nr { - set ::count 0 + # Start at 1 to be sure the "incr" in the test procs isn't the + # one creating the variable. + set $var 1 gdb_assert $assertion - gdb_assert { $::count == $expected_count } + gdb_assert { [set $var] == $expected_var_value } with_test_prefix cached { gdb_assert $assertion - gdb_assert { $::count == $expected_count } + gdb_assert { [set $var] == $expected_var_value } } } incr assertion_nr diff --git a/gdb/testsuite/lib/cache.exp b/gdb/testsuite/lib/cache.exp index b4c5fab2b98..bbe07387b21 100644 --- a/gdb/testsuite/lib/cache.exp +++ b/gdb/testsuite/lib/cache.exp @@ -78,31 +78,29 @@ proc gdb_cache_maybe_gdb_exit { name do_exit also_called } { return } - # To track if this proc has been called for NAME we create a - # global variable. In gdb_cleanup_globals (see gdb.exp) this - # global will be deleted when the test has finished. - set global_name __${name}__cached_gdb_exit_called - if { ![info exists ::${global_name}] } { + # To track if this proc has been called for NAME we use a global + # array. In gdb_cleanup_globals (see gdb.exp) this array will be + # deleted when the test has finished. + if { ![info exists ::gdb_caching_proc_called($name)] } { gdb_exit verbose -log "gdb_caching_proc $name caused gdb_exit to be called" - set ::${global_name} true - verbose -log " gdb_caching_proc $name marked as called" + set ::gdb_caching_proc_called($name) true + verbose -log " gdb_caching_proc $name marked as called" foreach other_name $also_called { verbose -log " gdb_caching_proc $other_name marked as called" - set global_name __${other_name}__cached_gdb_exit_called - set ::${global_name} true + set ::gdb_caching_proc_called($other_name) true } } } # A helper for gdb_caching_proc that handles the caching. -proc gdb_do_cache {name args} { +proc gdb_do_cache {name real_name args} { global gdb_data_cache objdir global GDB_PARALLEL - verbose -log "gdb_do_cache: $name ( $args )" + verbose -log "gdb_do_cache: $name $real_name ( $args )" # Normally, if we have a cached value, we skip computation and return # the cached value. If set to 1, instead don't skip computation and @@ -115,11 +113,15 @@ proc gdb_do_cache {name args} { set cache_verify 1 } + # NAME is always a fully qualified name here. Don't include the + # leading "::" in the cache file name. + set cache_file_name [string range $name 2 end] + # See if some other process wrote the cache file. Cache value per # "board" to handle runs with multiple options # (e.g. unix/{-m32,-64}) correctly. We use "file join" here # because we later use this in a real filename. - set cache_name [file join [target_info name] $name {*}$args] + set cache_name [file join [target_info name] $cache_file_name {*}$args] set is_cached 0 if {[info exists gdb_data_cache(${cache_name},value)]} { @@ -194,7 +196,6 @@ proc gdb_do_cache {name args} { set old_gdb_nested_caching_proc_calls $::gdb_nested_caching_proc_calls set ::gdb_nested_caching_proc_calls {} - set real_name gdb_real__$name set gdb_data_cache(${cache_name},value) [gdb_do_cache_wrap $real_name {*}$args] set gdb_data_cache(${cache_name},exit) $::gdb_exit_called set gdb_data_cache(${cache_name},also_called) \ @@ -276,15 +277,32 @@ proc gdb_do_cache {name args} { # proc gdb_caching_proc {name arglist body} { - # Define the underlying proc that we'll call. - set real_name gdb_real__$name - proc $real_name $arglist $body + # Figure out the caller's namespace. + set ns [uplevel 1 {namespace current}] + + # Normalize the advertised name. + if {[string match ::* $name]} { + set fq_name $name + } elseif {$ns eq "::"} { + set fq_name ::$name + } else { + set fq_name ${ns}::$name + } + + set tail [namespace tail $fq_name] + set qual [namespace qualifiers $fq_name] + + # The name of the underlying proc that we'll call. + set fq_real_name ${qual}::gdb_real__$tail + + # Define it. + proc $fq_real_name $arglist $body # Define the advertised proc. - set caching_proc_body [list gdb_do_cache $name] + set caching_proc_body [list gdb_do_cache $fq_name $fq_real_name] foreach arg $arglist { lappend caching_proc_body $$arg } set caching_proc_body [join $caching_proc_body] - proc $name $arglist $caching_proc_body + proc $fq_name $arglist $caching_proc_body } base-commit: d09eba07ca013e6b95eeafd67d79c32ebf6f28eb prerequisite-patch-id: 7193acb0815df9f5fbc926bb2169131538e88bd5 -- 2.51.0