Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Klaus Gerlicher <klaus.gerlicher@intel.com>
To: gdb-patches@sourceware.org
Cc: tom@tromey.com, aburgess@redhat.com, eliz@gnu.org, guinevere@redhat.com
Subject: [PATCH v9 3/6] gdb, cli: pass the argument of a set command to its callback.
Date: Mon,  7 Sep 2026 11:55:34 +0000	[thread overview]
Message-ID: <20260907115537.307049-4-klaus.gerlicher@intel.com> (raw)
In-Reply-To: <20260907115537.307049-1-klaus.gerlicher@intel.com>

From: Natalia Saiapova <natalia.saiapova@intel.com>

Passing the original argument to the callback is useful when a command
needs to distinguish being invoked with no argument from being invoked
with a specific value.

I am going to use it in
  gdb: refine commands to control scheduler locking.
to keep the old behaviour of the
  set scheduler-locking step
which should set both
  set scheduler-locking step on
  set scheduler-locking replay step on
To do this, the set-command needs to detect that it was issued without
arguments and have a special handling for this.

Without the special handling, the command
  set scheduler-locking step
would set only
  set scheduler-locking step on
---
 gdb/cli/cli-setshow.c               |   4 +-
 gdb/maint-test-settings.c           |  33 +++++---
 gdb/testsuite/gdb.base/settings.exp | 113 +++++++++++++++++++++-------
 gdb/testsuite/gdb.base/with.exp     |   3 +-
 4 files changed, 110 insertions(+), 43 deletions(-)

diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
index 7688da015de..1e0954a560d 100644
--- a/gdb/cli/cli-setshow.c
+++ b/gdb/cli/cli-setshow.c
@@ -335,6 +335,8 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
   if (arg == NULL)
     arg = "";
 
+  const char *org_arg = arg;
+
   gdb_assert (c->var.has_value ());
 
   switch (c->var->type ())
@@ -455,7 +457,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
       error (_("gdb internal error: bad var_type in do_setshow_command"));
     }
 
-  c->func (NULL, from_tty, c);
+  c->func (org_arg, from_tty, c);
 
   if (notify_command_param_changed_p (option_changed, c))
     {
diff --git a/gdb/maint-test-settings.c b/gdb/maint-test-settings.c
index f2e8a68a10f..6995f8b7bfb 100644
--- a/gdb/maint-test-settings.c
+++ b/gdb/maint-test-settings.c
@@ -67,6 +67,15 @@ static const char *const maintenance_test_settings_enums[] = {
 static const char *maintenance_test_settings_enum
   = maintenance_test_settings_xxx;
 
+/* The "maintenance set test-settings xxx" commands.  */
+
+static void
+maintenance_set_test_settings_cmd (const char *args, int from_tty,
+				   cmd_list_element *c)
+{
+  gdb_printf ("set-callback: arg='%s'\n", args == nullptr ? "" : args);
+}
+
 /* The "maintenance show test-settings xxx" commands.  */
 
 static void
@@ -96,7 +105,7 @@ Show GDB internal variables used for set/show command infrastructure testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			   nullptr, /* help_doc */
-			   nullptr, /* set_cmd */
+			   maintenance_set_test_settings_cmd,
 			   maintenance_show_test_settings_value_cmd,
 			   &maintenance_set_test_settings_list,
 			   &maintenance_show_test_settings_list);
@@ -106,7 +115,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 				nullptr, /* help_doc */
-				nullptr, /* set_cmd */
+				maintenance_set_test_settings_cmd,
 				maintenance_show_test_settings_value_cmd,
 				&maintenance_set_test_settings_list,
 				&maintenance_show_test_settings_list);
@@ -116,7 +125,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			    nullptr, /* help_doc */
-			    nullptr, /* set_cmd */
+			    maintenance_set_test_settings_cmd,
 			    maintenance_show_test_settings_value_cmd,
 			    &maintenance_set_test_settings_list,
 			    &maintenance_show_test_settings_list);
@@ -126,7 +135,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			   nullptr, /* help_doc */
-			   nullptr, /* set_cmd */
+			   maintenance_set_test_settings_cmd,
 			   maintenance_show_test_settings_value_cmd,
 			   &maintenance_set_test_settings_list,
 			   &maintenance_show_test_settings_list);
@@ -136,7 +145,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
      nullptr, /* help_doc */
-     nullptr, /* set_cmd */
+     maintenance_set_test_settings_cmd,
 			  maintenance_show_test_settings_value_cmd,
 			  &maintenance_set_test_settings_list,
 			  &maintenance_show_test_settings_list);
@@ -147,7 +156,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
      nullptr, /* help_doc */
-     nullptr, /* set_cmd */
+     maintenance_set_test_settings_cmd,
      maintenance_show_test_settings_value_cmd,
      &maintenance_set_test_settings_list,
      &maintenance_show_test_settings_list);
@@ -158,7 +167,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
      nullptr, /* help_doc */
-     nullptr, /* set_cmd */
+     maintenance_set_test_settings_cmd,
      maintenance_show_test_settings_value_cmd,
      &maintenance_set_test_settings_list,
      &maintenance_show_test_settings_list);
@@ -168,7 +177,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			    nullptr, /* help_doc */
-			    nullptr, /* set_cmd */
+			    maintenance_set_test_settings_cmd,
 			    maintenance_show_test_settings_value_cmd,
 			    &maintenance_set_test_settings_list,
 			    &maintenance_show_test_settings_list);
@@ -178,7 +187,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			    nullptr, /* help_doc */
-			    nullptr, /* set_cmd */
+			    maintenance_set_test_settings_cmd,
 			    maintenance_show_test_settings_value_cmd,
 			    &maintenance_set_test_settings_list,
 			    &maintenance_show_test_settings_list);
@@ -188,7 +197,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			     nullptr, /* help_doc */
-			     nullptr, /* set_cmd */
+			     maintenance_set_test_settings_cmd,
 			     maintenance_show_test_settings_value_cmd,
 			     &maintenance_set_test_settings_list,
 			     &maintenance_show_test_settings_list);
@@ -199,7 +208,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
      nullptr, /* help_doc */
-     nullptr, /* set_cmd */
+     maintenance_set_test_settings_cmd,
      maintenance_show_test_settings_value_cmd,
      &maintenance_set_test_settings_list,
      &maintenance_show_test_settings_list);
@@ -210,7 +219,7 @@ command used for internal testing."),
 command used for internal testing."), _("\
 command used for internal testing."),
 			nullptr, /* help_doc */
-			nullptr, /* set_cmd */
+			maintenance_set_test_settings_cmd,
 			maintenance_show_test_settings_value_cmd,
 			&maintenance_set_test_settings_list,
 			&maintenance_show_test_settings_list);
diff --git a/gdb/testsuite/gdb.base/settings.exp b/gdb/testsuite/gdb.base/settings.exp
index 2da8d47405b..54408bb64f4 100644
--- a/gdb/testsuite/gdb.base/settings.exp
+++ b/gdb/testsuite/gdb.base/settings.exp
@@ -34,6 +34,14 @@ if { ![readline_is_used] } {
     return
 }
 
+# Run a "maint set test-settings ..." command and expect the callback output.
+proc set_setting {cmd {test_name ""}} {
+    if {$test_name eq ""} {
+	set test_name $cmd
+    }
+    gdb_test $cmd "set-callback: arg='.*'" $test_name
+}
+
 # Test the show command SHOW_CMD.  EXPECTED_RE is the expected output.
 # Also verifies that $_gdb_maint_setting_str produces an equivalent output,
 # matching it with EXPECTED_RE.  EXPECTED_RE double quotes are escaped
@@ -52,6 +60,7 @@ if { ![readline_is_used] } {
 # This procedure makes it easier to make the test
 # name/message unique, since we test the "show" commands many times.
 # EXPECTED_RE is made part of the test name.
+
 proc show_setting {show_cmd expected_re {expected_re_escaped 0} {reset_value 0}} {
     global gdb_prompt
 
@@ -78,8 +87,8 @@ proc show_setting {show_cmd expected_re {expected_re_escaped 0} {reset_value 0}}
 
 	# Change the setting value to RESET_VALUE, set it back to setting_str_value
 	# and check we still have the original value.
-	gdb_test_no_output "maintenance set $maint_setting $reset_value" "str reset $reset_value"
-	gdb_test_no_output "maintenance set $maint_setting $setting_str_value" "str set again"
+	set_setting "maintenance set $maint_setting $reset_value" "str reset $reset_value"
+	set_setting "maintenance set $maint_setting $setting_str_value" "str set again"
 	gdb_test "$show_cmd" $expected_re "str show after reset+set again"
 
 	# Same test, but with value captured from $_gdb_maint_setting.
@@ -97,8 +106,8 @@ proc show_setting {show_cmd expected_re {expected_re_escaped 0} {reset_value 0}}
 	    }
 	}
 
-	gdb_test_no_output "maintenance set $maint_setting $reset_value" "reset $reset_value"
-	gdb_test_no_output "maintenance set $maint_setting $setting_value" "set again"
+	set_setting "maintenance set $maint_setting $reset_value" "reset $reset_value"
+	set_setting "maintenance set $maint_setting $setting_value" "set again"
 	gdb_test "$show_cmd" $expected_re "show after reset+set again"
     }
 }
@@ -152,20 +161,20 @@ proc test-integer {variant} {
 	check_type "test-settings $variant" "type = unsigned int"
     } else {
 	# Negative values are not accepted.
-	gdb_test_no_output "$set_cmd -1"
+	set_setting "$set_cmd -1"
 	show_setting "$show_cmd" "-1"
-	gdb_test_no_output "$set_cmd -2"
+	set_setting "$set_cmd -2"
 	show_setting "$show_cmd" "-2"
 	check_type "test-settings $variant" "type = int"
     }
 
     # Regular integer is accepted.
-    gdb_test_no_output "$set_cmd 999"
+    set_setting "$set_cmd 999"
     show_setting "$show_cmd" "999"
 
     if {$variant == "zinteger" || $variant == "zuinteger"} {
 	# 0 means 0.
-	gdb_test_no_output "$set_cmd 0"
+	set_setting "$set_cmd 0"
 	show_setting "$show_cmd" "0"
     } else {
 	# Either 0 or -1 mean unlimited.  Test both the number and
@@ -173,9 +182,9 @@ proc test-integer {variant} {
 	# abbreviations.
 
 	if {$variant == "zuinteger-unlimited"} {
-	    gdb_test_no_output "$set_cmd -1"
+	    set_setting "$set_cmd -1"
 	} else {
-	    gdb_test_no_output "$set_cmd 0"
+	    set_setting "$set_cmd 0"
 	}
 	show_setting "$show_cmd" "unlimited"
 
@@ -192,10 +201,10 @@ proc test-integer {variant} {
 	} {
 	    # Alternate between integer and unlimited, to make sure the
 	    # setting really took effect.
-	    gdb_test_no_output "$set_cmd 1"
+	    set_setting "$set_cmd 1"
 	    show_setting "$show_cmd" "1"
 
-	    gdb_test_no_output "$set_cmd $value"
+	    set_setting "$set_cmd $value"
 	    show_setting "$show_cmd" "unlimited"
 	}
     }
@@ -312,10 +321,10 @@ proc_with_prefix test-boolean {} {
 	"enabl"
 	"enable"
     } {
-	gdb_test_no_output "$set_cmd off"
+	set_setting "$set_cmd off"
 	show_setting "$show_cmd" "off"
 
-	gdb_test_no_output "$set_cmd $value"
+	set_setting "$set_cmd $value"
 	show_setting "$show_cmd" "on"
     }
 
@@ -335,10 +344,10 @@ proc_with_prefix test-boolean {} {
 	"disabl"
 	"disable"
     } {
-	gdb_test_no_output "$set_cmd on"
+	set_setting "$set_cmd on"
 	show_setting "$show_cmd" "on"
 
-	gdb_test_no_output "$set_cmd $value"
+	set_setting "$set_cmd $value"
 	show_setting "$show_cmd" "off"
     }
 
@@ -399,10 +408,10 @@ proc_with_prefix test-auto-boolean {} {
 	"enabl"
 	"enable"
     } {
-	gdb_test_no_output "$set_cmd off"
+	set_setting "$set_cmd off"
 	show_setting "$show_cmd" "off"
 
-	gdb_test_no_output "$set_cmd $value"
+	set_setting "$set_cmd $value"
 	show_setting "$show_cmd" "on"
     }
 
@@ -420,10 +429,10 @@ proc_with_prefix test-auto-boolean {} {
 	"disabl"
 	"disable"
     } {
-	gdb_test_no_output "$set_cmd on"
+	set_setting "$set_cmd on"
 	show_setting "$show_cmd" "on"
 
-	gdb_test_no_output "$set_cmd $value"
+	set_setting "$set_cmd $value"
 	show_setting "$show_cmd" "off"
     }
 
@@ -434,10 +443,10 @@ proc_with_prefix test-auto-boolean {} {
 	"auto"
 	"-1"
     } {
-	gdb_test_no_output "$set_cmd on"
+	set_setting "$set_cmd on"
 	show_setting "$show_cmd" "on"
 
-	gdb_test_no_output "$set_cmd $value"
+	set_setting "$set_cmd $value"
 	show_setting "$show_cmd" "auto"
     }
 
@@ -497,11 +506,11 @@ proc_with_prefix test-enum {} {
 
     # Various valid values.  Test both full value names and
     # abbreviations.
-    gdb_test_no_output "$set_cmd x"
+    set_setting "$set_cmd x"
     show_setting "$show_cmd" "xxx" 0 "zzz"
-    gdb_test_no_output "$set_cmd yy"
+    set_setting "$set_cmd yy"
     show_setting "$show_cmd" "yyy" 0 "zzz"
-    gdb_test_no_output "$set_cmd zzz"
+    set_setting "$set_cmd zzz"
     show_setting "$show_cmd" "zzz" 0 "yyy"
 
     check_type "test-settings enum" "type = char \\\[4\\\]"
@@ -548,17 +557,17 @@ proc test-string {variant} {
     }
 
     # A string value.
-    gdb_test_no_output "$set_cmd hello world"
+    set_setting "$set_cmd hello world"
     show_setting "$show_cmd" "hello world"
 
     check_type "test-settings $variant" "type = char \\\[$::positive\\\]"
 
     # A quoted string value.
     if {$variant == "string"} {
-	gdb_test_no_output "$set_cmd \"hello world\""
+	set_setting "$set_cmd \"hello world\""
 	show_setting "$show_cmd" "\\\\\"hello world\\\\\"" 1
     } else {
-	gdb_test_no_output "$set_cmd \"hello world\""
+	set_setting "$set_cmd \"hello world\""
 	show_setting "$show_cmd" "\"hello world\""
     }
 
@@ -571,7 +580,7 @@ proc test-string {variant} {
 	    # Check the value didn't change.
 	    show_setting "$show_cmd" "\"hello world\""
 	} else {
-	    gdb_test_no_output "$set_cmd"
+	    set_setting "$set_cmd"
 	    # This odd expected output here is because we expect GDB to
 	    # emit a single blank line as a result of this command.
 	    gdb_test -nonl "$show_cmd" "^\r\n" "$show_cmd: empty second time"
@@ -666,3 +675,49 @@ foreach variant {
 }
 
 test-setting-error
+
+# Verify that the set-command callback receives the original argument
+# string, including for integer settings where parse_cli_var_integer
+# advances the internal pointer.
+proc_with_prefix test-set-callback {} {
+    # Integer types: the original arg string must reach the callback
+    # unchanged even though parse_cli_var_integer moves the pointer.
+    foreach_with_prefix variant {
+	uinteger integer zinteger zuinteger zuinteger-unlimited
+    } {
+	set set_cmd "maint set test-settings $variant"
+
+	gdb_test "$set_cmd 999" \
+	    "set-callback: arg='999'" \
+	    "integer arg passed through"
+
+	if {$variant == "uinteger" || $variant == "integer"
+	    || $variant == "zuinteger-unlimited"} {
+	    gdb_test "$set_cmd unlimited" \
+		"set-callback: arg='unlimited'" \
+		"unlimited arg passed through"
+	}
+    }
+
+    # Boolean: empty arg (no argument given) must arrive as "".
+    gdb_test "maint set test-settings boolean" \
+	"set-callback: arg=''" \
+	"boolean no-arg callback"
+
+    # Boolean: explicit value.
+    gdb_test "maint set test-settings boolean on" \
+	"set-callback: arg='on'" \
+	"boolean on arg passed through"
+
+    # Enum: arg must be the full original token.
+    gdb_test "maint set test-settings enum yyy" \
+	"set-callback: arg='yyy'" \
+	"enum arg passed through"
+
+    # String: arg must be the literal string typed.
+    gdb_test "maint set test-settings string hello" \
+	"set-callback: arg='hello'" \
+	"string arg passed through"
+}
+
+test-set-callback
diff --git a/gdb/testsuite/gdb.base/with.exp b/gdb/testsuite/gdb.base/with.exp
index 101c6dcccf9..aa44a23c8c0 100644
--- a/gdb/testsuite/gdb.base/with.exp
+++ b/gdb/testsuite/gdb.base/with.exp
@@ -35,11 +35,12 @@ clean_restart $testfile
 # level, but maps to -1 internally.
 
 proc test_with {setting values} {
+    set cb "set-callback: arg='.*'"
     foreach val1 $values {
 	foreach val2 $values {
 	    gdb_test \
 		"maint with test-settings $setting $val1 -- maint with test-settings $setting $val2 -- p 1" \
-		" = 1"
+		"${cb}\r\n${cb}\r\n\\$\[0-9\]+ = 1\r\n${cb}\r\n${cb}"
 	}
     }
 }
-- 
2.34.1

________________________________________
Intel Deutschland GmbH 

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany 

Tel: +49 (89) 99143-0 

www.intel.de 

Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman

Chairperson of the Supervisory Board: Sonja Pierer

Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


  parent reply	other threads:[~2026-09-07 11:58 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-07 11:55 [PATCH v9 0/6] gdb: refine scheduler locking settings Klaus Gerlicher
2026-09-07 11:55 ` [PATCH v9 1/6] gdb: use schedlock_applies in user_visible_resume_ptid Klaus Gerlicher
2026-09-07 11:55 ` [PATCH v9 2/6] gdb, cli: remove left-over code from "set_logging_on" Klaus Gerlicher
2026-09-07 11:55 ` Klaus Gerlicher [this message]
2026-09-07 11:55 ` [PATCH v9 4/6] gdb: change the internal representation of scheduler locking Klaus Gerlicher
2026-09-07 11:55 ` [PATCH v9 5/6] gdb: refine commands to control " Klaus Gerlicher
2026-09-07 11:55 ` [PATCH v9 6/6] gdb: add eval option to lock the scheduler during infcalls Klaus Gerlicher

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=20260907115537.307049-4-klaus.gerlicher@intel.com \
    --to=klaus.gerlicher@intel.com \
    --cc=aburgess@redhat.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=guinevere@redhat.com \
    --cc=tom@tromey.com \
    /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