From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCH 2/4] gdb/testsuite: improve with_override
Date: Mon, 3 Jun 2024 19:16:53 +0100 [thread overview]
Message-ID: <d1c0e844f31d8277ae9a7adc82cac2dc51a6d9d1.1717438458.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1717438458.git.aburgess@redhat.com>
I wanted to use 'with_override' to override a proc, but within the
overridden proc I wanted to call the original function. I could just
write my own version of 'with_override' that does what I want...
... or I could extend the existing 'with_override' to include this new
functionality, which is what I've done in this commit.
You can now do this:
with_override some_proc new_proc save_name {
... body ....
}
Now, while BODY is executing calls to 'some_proc' will actually result
in calling 'new_proc'. However, calling 'save_name' will call the
original definition of 'some_proc'.
If 'save_name' already exists when 'with_override' is called then the
original value of 'save_name' will be backed up and then restored once
the with_override has completed.
If you don't need the new functionality then the old behaviour still
works just fine, i.e.:
with_override some_proc new_proc {
... body ...
}
My use of this new functionality will appear in a later commit, but
for now I've added some unit-tests for the new functionality.
---
gdb/testsuite/gdb.testsuite/with-override.exp | 44 ++++++++++++++
gdb/testsuite/lib/gdb.exp | 60 +++++++++++++++++--
2 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/gdb/testsuite/gdb.testsuite/with-override.exp b/gdb/testsuite/gdb.testsuite/with-override.exp
index a0a49625372..12467061ba7 100644
--- a/gdb/testsuite/gdb.testsuite/with-override.exp
+++ b/gdb/testsuite/gdb.testsuite/with-override.exp
@@ -26,10 +26,18 @@ proc foo2 {} {
return 2
}
+# Ensure that 'old_foo' doesn't exist.
+if { [info procs old_foo] != "" } {
+ rename old_foo ""
+}
+
with_test_prefix no-args {
with_test_prefix before {
gdb_assert { [foo] == 0 }
+ gdb_assert { [foo1] == 1 }
+ gdb_assert { [foo2] == 2 }
+ gdb_assert { [info procs old_foo] == "" } "old_foo does not exist"
}
with_override foo foo1 {
@@ -44,8 +52,30 @@ with_test_prefix no-args {
}
}
+ with_override foo foo1 old_foo {
+ with_test_prefix old_foo {
+ with_test_prefix before {
+ gdb_assert { [old_foo] == 0 }
+ gdb_assert { [foo] == 1 }
+ }
+
+ with_override foo foo2 old_foo {
+ gdb_assert { [old_foo] == 1 }
+ gdb_assert { [foo] == 2 }
+ }
+
+ with_test_prefix after {
+ gdb_assert { [old_foo] == 0 }
+ gdb_assert { [foo] == 1 }
+ }
+ }
+ }
+
with_test_prefix after {
gdb_assert { [foo] == 0 }
+ gdb_assert { [foo1] == 1 }
+ gdb_assert { [foo2] == 2 }
+ gdb_assert { [info procs old_foo] == "" } "old_foo does not exist"
}
}
@@ -63,6 +93,7 @@ with_test_prefix default-arg {
gdb_assert { [foo] == 1 }
gdb_assert { [foo 0] == 1 }
gdb_assert { [foo 1] == 2 }
+ gdb_assert { [info procs old_foo] == "" } "old_foo does not exist"
}
with_override foo foo_plus_1 {
@@ -73,9 +104,22 @@ with_test_prefix default-arg {
}
}
+ with_override foo foo_plus_1 old_foo {
+ with_test_prefix old_foo {
+ gdb_assert { [foo] == 2 }
+ gdb_assert { [foo 0] == 2 }
+ gdb_assert { [foo 1] == 3 }
+
+ gdb_assert { [old_foo] == 1 }
+ gdb_assert { [old_foo 0] == 1 }
+ gdb_assert { [old_foo 1] == 2 }
+ }
+ }
+
with_test_prefix after {
gdb_assert { [foo] == 1 }
gdb_assert { [foo 0] == 1 }
gdb_assert { [foo 1] == 2 }
+ gdb_assert { [info procs old_foo] == "" } "old_foo does not exist"
}
}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index cdc3721a1cd..8235d4f28eb 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -9726,10 +9726,18 @@ proc info_args_with_defaults { name } {
return $args
}
+# Use as either:
+#
+# with_override NAME OVERRIDE BODY
+# with_override NAME OVERRIDE SAVE_NAME BODY
+#
# Override proc NAME to proc OVERRIDE for the duration of the execution of
-# BODY.
+# a BODY.
+#
+# If the SAVE_NAME form is used then NAME will be available as
+# SAVE_NAME for the duration of BODY.
-proc with_override { name override body } {
+proc with_override { name override args } {
# Implementation note: It's possible to implement the override using
# rename, like this:
# rename $name save_$name
@@ -9742,11 +9750,43 @@ proc with_override { name override body } {
# - the override is no longer available under its original name during
# the override
# So, we use this more elaborate but cleaner mechanism.
+ #
+ # When the SAVE_NAME argument is provided to with_override then we
+ # do use rename, but we first backup any existing proc called
+ # SAVE_NAME, delete the existing SAVE_NAME, and only then do the
+ # rename.
+
+ if { [llength $args] == 1 } {
+ set save_name ""
+ set body [lindex $args 0]
+ } elseif { [llength $args] == 2 } {
+ set save_name [lindex $args 0]
+ set body [lindex $args 1]
+ } else {
+ perror "invalid argument count to with_override: [llength $args]"
+ return
+ }
+
+ # If the user wants to save the original proc, but the name they'd
+ # like to save into already exists then capture details of the
+ # thing we're about to overwrite.
+ if { $save_name != "" && [info procs $save_name] != "" } {
+ set save_name_args [info_args_with_defaults $save_name]
+ set save_name_body [info body $save_name]
+ rename $save_name ""
+ set save_name_existed true
+ } else {
+ set save_name_existed false
+ }
# Save the old proc, if it exists.
if { [info procs $name] != "" } {
- set old_args [info_args_with_defaults $name]
- set old_body [info body $name]
+ if { $save_name != "" } {
+ rename $name $save_name
+ } else {
+ set old_args [info_args_with_defaults $name]
+ set old_body [info body $name]
+ }
set existed true
} else {
set existed false
@@ -9762,11 +9802,21 @@ proc with_override { name override body } {
# Restore old proc if it existed on entry, else delete it.
if { $existed } {
- eval proc $name {$old_args} {$old_body}
+ if { $save_name != "" } {
+ rename $name ""
+ rename $save_name $name
+ } else {
+ eval proc $name {$old_args} {$old_body}
+ }
} else {
rename $name ""
}
+ # Restore the proc we saved over, if necessary.
+ if { $save_name_existed } {
+ eval proc $save_name {$save_name_args} {$save_name_body}
+ }
+
# Return as appropriate.
if { $code == 1 } {
global errorInfo errorCode
--
2.25.4
next prev parent reply other threads:[~2024-06-03 18:18 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-03 18:16 [PATCH 0/4] gdb/testsuite: remove can_spawn_for_attach_1 Andrew Burgess
2024-06-03 18:16 ` [PATCH 1/4] gdb/testsuite: remove trailing \r from rust_llvm_version result Andrew Burgess
2024-06-04 13:51 ` Tom Tromey
2024-06-05 9:20 ` Andrew Burgess
2024-06-03 18:16 ` Andrew Burgess [this message]
2024-06-03 18:16 ` [PATCH 3/4] gdb/testsuite: restructure gdb_data_cache (lib/cache.exp) Andrew Burgess
2024-06-03 18:16 ` [PATCH 4/4] gdb/testsuite: track if a caching proc calls gdb_exit or not Andrew Burgess
2024-08-07 6:05 ` Luis Machado
2024-08-07 9:16 ` Andrew Burgess
2024-08-07 10:00 ` Andrew Burgess
2024-08-07 10:08 ` Luis Machado
2024-08-07 10:12 ` Luis Machado
2024-08-07 12:45 ` Andrew Burgess
2024-08-07 14:31 ` Andrew Burgess
2024-08-07 18:35 ` Luis Machado
2024-08-08 10:20 ` Luis Machado
2024-08-08 10:50 ` Luis Machado
2024-08-08 11:08 ` Luis Machado
2024-08-08 14:50 ` Andrew Burgess
2024-08-09 11:29 ` Luis Machado
2024-08-13 16:30 ` Andrew Burgess
2024-08-14 13:06 ` Luis Machado
2024-08-14 17:00 ` Andrew Burgess
2024-08-15 6:03 ` Luis Machado
2024-08-20 15:25 ` Andrew Burgess
2024-06-04 9:06 ` [PATCH 0/4] gdb/testsuite: remove can_spawn_for_attach_1 Andrew Burgess
2024-06-05 13:27 ` [PATCHv2 0/2] " Andrew Burgess
2024-06-05 13:27 ` [PATCHv2 1/2] gdb/testsuite: restructure gdb_data_cache (lib/cache.exp) Andrew Burgess
2024-06-05 13:27 ` [PATCHv2 2/2] gdb/testsuite: track if a caching proc calls gdb_exit or not Andrew Burgess
2024-07-28 8:54 ` [PUSHED 0/2] gdb/testsuite: remove can_spawn_for_attach_1 Andrew Burgess
2024-07-28 8:54 ` [PUSHED 1/2] gdb/testsuite: restructure gdb_data_cache (lib/cache.exp) Andrew Burgess
2024-07-28 8:54 ` [PUSHED 2/2] gdb/testsuite: track if a caching proc calls gdb_exit or not Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d1c0e844f31d8277ae9a7adc82cac2dc51a6d9d1.1717438458.git.aburgess@redhat.com \
--to=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox