Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Klaus Gerlicher <klaus.gerlicher@intel.com>, gdb-patches@sourceware.org
Cc: tom@tromey.com, guinevere@redhat.com, eliz@gnu.org
Subject: Re: [PATCH v8 5/6] gdb: refine commands to control scheduler locking.
Date: Fri, 24 Jul 2026 10:34:07 +0100	[thread overview]
Message-ID: <87jyqkoho0.fsf@redhat.com> (raw)
In-Reply-To: <20260722102746.131536-6-klaus.gerlicher@intel.com>

Klaus Gerlicher <klaus.gerlicher@intel.com> writes:

> From: Natalia Saiapova <natalia.saiapova@intel.com>
>
> In this patch, we introduce new command options for set/show scheduler
> locking.  New options give the user a finer control over the scheduler.
>
> Introduce
> set scheduler-locking <continue | replay step | replay continue | step> <on | off>
> show scheduler-locking <continue | replay step | replay continue | step>
>
> For example, with these commands a user can get a combined scheduler locking
> for stepping commands during the normal execution and for all commands in
> replay mode.
>
> The existing scheduler-locking settings still exist and work as shortcuts.
>
>   set scheduler-locking step
> is equivalent to
>   set scheduler-locking continue off
>   set scheduler-locking replay continue off
>   set scheduler-locking replay step on
>   set scheduler-locking step on
>
>   set scheduler-locking on
> is equivalent to
>   set scheduler-locking continue on
>   set scheduler-locking replay continue on
>   set scheduler-locking replay step on
>   set scheduler-locking step on
>
>   set scheduler-locking replay
> is equivalent to
>   set scheduler-locking continue off
>   set scheduler-locking replay continue on
>   set scheduler-locking replay step on
>   set scheduler-locking step off
>
>   set scheduler-locking off
> is equivalent to
>   set scheduler-locking continue off
>   set scheduler-locking replay continue off
>   set scheduler-locking replay step off
>   set scheduler-locking step off
>
> This is bound to the structure we introduced in the previous commit:
>   gdb: change the internal representation of scheduler locking.
>
> To introduce it under scheduler-locking I had to change the way the show
> command works.
>
>   (gdb) show scheduler-locking
>   scheduler-locking continue:  "off"  Scheduler locking for continuing
>   commands is "off" during normal execution.
>   scheduler-locking replay continue:  "on"  Scheduler locking for
>   continuing commands is "on" during replay mode.
>   scheduler-locking replay step:  "on"  Scheduler locking for stepping
>   commands is "on" during replay mode.
>   scheduler-locking step:  "off"  Scheduler locking for stepping commands
>   is "off" during normal execution.
>
>   (gdb) show scheduler-locking replay
>   scheduler-locking replay continue:  "on"  Scheduler locking for
>   continuing commands is "on" during replay mode.
>   scheduler-locking replay step:  "on"  Scheduler locking for stepping
>   commands is "on" during replay mode.
>
>   (gdb) show scheduler-locking replay step
>   "on"  Scheduler locking for stepping commands is "on" during replay mode.
>
>   (gdb) show scheduler-locking continue
>   "off"  Scheduler locking for continuing commands is "off" during
>   normal execution.
>
> Note, there is a small inconsistency with the "set scheduler-locking step".
> If we did not keep the older way of setting the scheduler locking, command
>   set scheduler-locking step
> would be the same as
>   set scheduler-locking step on
> while to be backward compatible, we have it as
>   set scheduler-locking step on
>   set scheduler-locking replay step on
>
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
> ---
>  gdb/NEWS                                      |  21 ++
>  gdb/doc/gdb.texinfo                           |  66 +++++-
>  gdb/infrun.c                                  | 224 ++++++++++++++----
>  .../gdb.mi/user-selected-context-sync.exp     |  22 +-
>  .../gdb.threads/hand-call-in-threads.exp      |  10 +-
>  .../multiple-successive-infcall.exp           |   6 +-
>  gdb/testsuite/gdb.threads/schedlock.exp       |  80 ++++++-
>  gdb/testsuite/lib/gdb.exp                     |  70 ++++--
>  8 files changed, 397 insertions(+), 102 deletions(-)
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 8f40ca5cb11..30d0637518b 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -902,6 +902,27 @@ list .
>    lines.  This makes it more obvious that there is no information, as opposed
>    to implying there is no inferior loaded.
>  
> +set scheduler-locking <command type> (on|off)
> +show scheduler-locking <command type>
> +  where <command-type> is one of the following:

This sentence should start wit ha capital letter.

Thanks,
Andrew

> +    continue | replay continue | replay step | step.
> +  Extend the scheduler locking settings with a set of set/show
> +  commands, which can be used individually to control the scheduler during
> +  stepping and continuing commands.  Stepping commands include step, stepi,
> +  next.  Continuing commands include continue, finish, until, jump, return.
> +    'continue' -- when on, the scheduler is locked during continuing commands
> +    in normal mode.
> +    'replay continue' -- when on, the scheduler is locked during continuing
> +    commands in replay mode.
> +    'replay step' -- when on, the scheduler is locked during stepping
> +    commands in replay mode.
> +    'step' -- when on, the scheduler is locked during stepping commands
> +    in normal mode.
> +  The older scheduler locking settings can be used as shortcuts, their behavior
> +  is preserved.
> +  The output of "show scheduler-locking" has changed to support the new
> +  settings.
> +
>  * New commands
>  
>  info missing-debug-handler
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 0030698dcee..fbf0f6e1da6 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -7456,28 +7456,63 @@ On some OSes, you can modify @value{GDBN}'s default behavior by
>  locking the OS scheduler to allow only a single thread to run.
>  
>  @table @code
> -@item set scheduler-locking @var{mode}
>  @cindex scheduler-locking
> +@item set scheduler-locking @var{type} [@code{on}|@code{off}]
> +@cindex scheduler locking type
> +@cindex lock scheduler
> +Set the scheduler locking settings.  It applies to normal execution,
> +record mode, and replay mode.  You can configure scheduler locking separately
> +for stepping and continuing commands.  Examples of stepping commands are:
> +@samp{step}, @samp{stepi}, @samp{next}.  Examples of continuing commands are
> +@samp{continue}, @samp{finish}, @samp{jump}, @samp{until}, @samp{return} or
> +inferior function calls.
> +
> +The following @var{type}-settings are available.  When a setting is
> +@code{on}, the scheduler is locked: other threads may not preempt the
> +current thread, so that the focus of debugging does not change unexpectedly.
> +
> +@table @code
> +@item continue
> +Applies to continuing commands during normal execution and record modes.
> +This setting is @code{off} by default.
> +
> +@item replay continue
> +Applies to continuing commands during replay mode.  This setting is
> +@code{on} by default.
> +
> +@item replay step
> +Applies to stepping commands during replay mode.  This setting is
> +@code{on} by default.
> +
> +@item step
> +Applies to stepping commands during normal execution and record modes.
> +This setting is @code{off} by default.
> +
> +@end table
> +
> +@item set scheduler-locking @var{shortcut-mode}
>  @cindex scheduler locking mode
>  @cindex lock scheduler
> -Set the scheduler locking mode.  It applies to normal execution,
> -record mode, and replay mode.  @var{mode} can be one of
> -the following:
> +Set the scheduler locking mode.  It applies to normal execution, record mode,
> +and replay mode.  @var{shortcut-mode} is a shortcut to set several scheduler
> +locking types at once and can be one of the following:
>  
>  @table @code
>  @item off
> -There is no locking and any thread may run at any time.
> +There is no locking and any thread may run at any time.  This is
> +equivalent to setting all type options to @code{off}.
>  
>  @item on
> -Only the current thread may run when the inferior is resumed.  New
> -threads created by the resumed thread are held stopped at their entry
> -point, before they execute any instruction.
> +Only the current thread may run when the inferior is resumed.  New threads
> +created by the resumed thread are held stopped at their entry point, before
> +they execute any instruction.  This is equivalent to setting all type options
> +to @code{on}.
>  
>  @item step
>  Behaves like @code{on} when stepping, and @code{off} otherwise.
>  Threads other than the current never get a chance to run when you
> -step, and they are completely free to run when you use commands like
> -@samp{continue}, @samp{until}, or @samp{finish}.
> +step, and they are completely free to run when you use continuing
> +commands.
>  
>  This mode optimizes for single-stepping; it prevents other threads
>  from preempting the current thread while you are stepping, so that the
> @@ -7486,9 +7521,18 @@ another thread hits a breakpoint during its timeslice, @value{GDBN}
>  does not change the current thread away from the thread that you are
>  debugging.
>  
> +This is equivalent to set @samp{scheduler-locking step} and
> +@samp{scheduler-locking replay step} to @code{on}, while other settings
> +are @code{off}.
> +
>  @item replay
>  Behaves like @code{on} in replay mode, and @code{off} in either record
>  mode or during normal execution.  This is the default mode.
> +
> +This is equivalent to set @samp{scheduler-locking replay continue} and
> +@samp{scheduler-locking replay step} to @code{on}, while other settings
> +are @code{off}.
> +
>  @end table
>  
>  @item show scheduler-locking
> @@ -34703,7 +34747,7 @@ the end or beginning of a replay log if one is being used.
>  @end itemize
>  In all-stop mode (@pxref{All-Stop
>  Mode}), may resume only one thread, or all threads, depending on the
> -value of the @samp{scheduler-locking} variable.  If @samp{--all} is
> +value of the @samp{scheduler-locking} variables.  If @samp{--all} is
>  specified, all threads (in all inferiors) will be resumed.  The @samp{--all} option is
>  ignored in all-stop mode.  If the @samp{--thread-group} options is
>  specified, then all threads in that thread group are resumed.
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index 0eb890bbbc1..b6f7721dbf3 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -75,6 +75,8 @@
>  #include "extension.h"
>  #include "disasm.h"
>  #include "interps.h"
> +#include "cli/cli-decode.h"
> +#include <set>
>  #include "finish-thread-state.h"
>  #include "buffered-streams.h"
>  
> @@ -116,6 +118,12 @@ static bool schedlock_applies_to_opts (const schedlock_options &, bool step);
>  
>  static void handle_process_exited (struct execution_control_state *ecs);
>  
> +/* Command lists for the scheduler locking.  */
> +static cmd_list_element *schedlock_set_cmdlist;
> +static cmd_list_element *schedlock_show_cmdlist;
> +static cmd_list_element *schedlock_set_replay_cmdlist;
> +static cmd_list_element *schedlock_show_replay_cmdlist;
> +
>  /* Asynchronous signal handler registered as event loop source for
>     when we have pending events ready to be passed to the core.  */
>  static struct async_event_handler *infrun_async_inferior_event_token;
> @@ -2398,7 +2406,8 @@ struct schedlock_options
>  
>      operator bool () const { return value; }
>      const char *c_str () const { return value ? "on" : "off"; }
> -    /* Set new value.  Return true, if the value has changed.  */
> +    /* Set new value.  Return true, if the value has changed.
> +       Also notifies the observer, if the value has changed.  */
>      bool set (bool new_value);
>    };
>  
> @@ -2425,6 +2434,9 @@ schedlock_options::option::set (bool new_value)
>    if (value != new_value)
>      {
>        value = new_value;
> +      std::string param_name = "scheduler-locking " + name;
> +
> +      interps_notify_param_changed (param_name.c_str (), c_str ());
>        return true;
>      }
>  
> @@ -2445,15 +2457,6 @@ static const char schedlock_off[] = "off";
>  static const char schedlock_on[] = "on";
>  static const char schedlock_step[] = "step";
>  static const char schedlock_replay[] = "replay";
> -static const char *const scheduler_enums[] = {
> -  schedlock_off,
> -  schedlock_on,
> -  schedlock_step,
> -  schedlock_replay,
> -  nullptr
> -};
> -
> -static const char *scheduler_mode = schedlock_replay;
>  
>  schedlock schedlock {
>    {
> @@ -2482,35 +2485,89 @@ set_schedlock_shortcut_option (const char *shortcut)
>    /* Check that we got a valid shortcut option.  */
>    gdb_assert (is_on || is_step || is_replay || is_off);
>  
> -  schedlock.normal.cont.set (is_on);
> -  schedlock.normal.step.set (is_on || is_step);
> -  schedlock.replay.cont.set (is_on || is_replay);
> -  schedlock.replay.step.set (is_on || is_replay || is_step);
> +  bool any_changed = schedlock.normal.cont.set (is_on);
> +  any_changed = schedlock.normal.step.set (is_on || is_step) || any_changed;
> +  any_changed = schedlock.replay.cont.set (is_on || is_replay) || any_changed;
> +  any_changed = schedlock.replay.step.set (is_on || is_replay || is_step)
> +    || any_changed;
> +
> +  /* If at least one parameter has changed, notify the observer
> +     in the old-fashioned way.  */
> +  if (any_changed)
> +    interps_notify_param_changed ("scheduler-locking", shortcut);
>  }
>  
> +/* Default callback for set methods of scheduler locking options.
> +   Checks that the scheduler locking is supported.
> +   If no, it reverts all options to "off" and throws an error.  */
> +
>  static void
> -show_scheduler_mode (struct ui_file *file, int from_tty,
> -		     struct cmd_list_element *c, const char *value)
> +set_schedlock_callback (const char *args, int from_tty, cmd_list_element *c)
>  {
> -  gdb_printf (file,
> -	      _("Mode for locking scheduler "
> -		"during execution is \"%s\".\n"),
> -	      value);
> +  if (target_can_lock_scheduler ())
> +    return;
> +
> +  /* Set scheduler locking off and error out.  */
> +  set_schedlock_shortcut_option (schedlock_off);
> +  error (_("Target '%s' cannot support this command."), target_shortname ());
>  }
>  
> +/* Support for shortcut schedlock options: "on", "off", "step", "replay".  */
> +
>  static void
> -set_schedlock_func (const char *args, int from_tty, struct cmd_list_element *c)
> +set_schedlock_step (const char *args, int from_tty, cmd_list_element *c)
>  {
> -  if (!target_can_lock_scheduler ())
> -    {
> -      scheduler_mode = schedlock_off;
> -      /* Set scheduler locking off.  */
> -      set_schedlock_shortcut_option (schedlock_off);
> -      error (_("Target '%s' cannot support this command."),
> -	     target_shortname ());
> -    }
> +  if (!args || !*args)
> +    set_schedlock_shortcut_option (schedlock_step);
> +  set_schedlock_callback (args, from_tty, nullptr);
> +}
>  
> -  set_schedlock_shortcut_option (scheduler_mode);
> +static void
> +set_schedlock_replay (const char *args, int from_tty)
> +{
> +  set_schedlock_shortcut_option (schedlock_replay);
> +  set_schedlock_callback (args, from_tty, nullptr);
> +}
> +
> +static void
> +set_schedlock_on (const char *args, int from_tty)
> +{
> +  set_schedlock_shortcut_option (schedlock_on);
> +  set_schedlock_callback (args, from_tty, nullptr);
> +}
> +
> +static void
> +set_schedlock_off (const char *args, int from_tty)
> +{
> +  set_schedlock_shortcut_option (schedlock_off);
> +  set_schedlock_callback (args, from_tty, nullptr);
> +}
> +
> +/* Default method to show a single option of scheduler locking.  */
> +
> +static void
> +show_schedlock_option (ui_file *file, int from_tty,
> +		       cmd_list_element *c, const char *value)
> +{
> +  gdb_assert (c->prefix != nullptr);
> +  const char *mode;
> +  if (strcmp (c->prefix->name, "replay") == 0)
> +    mode = "replay mode";
> +  else if (strcmp (c->prefix->name, "scheduler-locking") == 0)
> +    mode = "normal execution";
> +  else
> +    gdb_assert_not_reached ("Unexpected command prefix.");
> +
> +  const char *type;
> +  if (strcmp (c->name, "step") == 0)
> +    type = "stepping commands";
> +  else if (strcmp (c->name, "continue") == 0)
> +    type = "continuing commands";
> +  else
> +    gdb_assert_not_reached ("Unexpected command name.");
> +
> +  gdb_printf (file, _("\"%s\"  Scheduler locking for %s is "
> +		      "\"%s\" during the %s.\n"), value, type, value, mode);
>  }
>  
>  /* True if execution commands resume all threads of all processes by
> @@ -8648,15 +8705,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
>  	  return true;
>  	}
>  
> -      /* If scheduler locking applies even if not stepping, there's no
> -	 need to walk over threads.  Above we've checked whether the
> -	 current thread is stepping.  If some other thread not the
> -	 event thread is stepping, then it must be that scheduler
> -	 locking is not in effect.  */
> -      if (schedlock_applies (ecs->event_thread))
> -	return false;
> -
> -      /* Otherwise, we no longer expect a trap in the current thread.
> +      /* We no longer expect a trap in the current thread.
>  	 Clear the trap_expected flag before switching back -- this is
>  	 what keep_going does as well, if we call it.  */
>        ecs->event_thread->control.trap_expected = 0;
> @@ -11023,21 +11072,92 @@ By default, the debugger will use the same inferior."),
>  			show_follow_exec_mode_string,
>  			&setlist, &showlist);
>  
> -  add_setshow_enum_cmd ("scheduler-locking", class_run,
> -			scheduler_enums, &scheduler_mode, _("\
> -Set mode for locking scheduler during execution."), _("\
> -Show mode for locking scheduler during execution."), _("\
> -off    == no locking (threads may preempt at any time)\n\
> -on     == full locking (no thread except the current thread may run)\n\
> -	  This applies to both normal execution and replay mode.\n\
> -step   == scheduler locked during stepping commands (step, next, stepi, nexti).\n\
> -	  In this mode, other threads may run during other commands.\n\
> -	  This applies to both normal execution and replay mode.\n\
> -replay == scheduler locked in replay mode and unlocked during normal execution."),
> -			set_schedlock_func,	/* traps on target vector */
> -			show_scheduler_mode,
> +  /* Commands for set/show scheduler-locking.  */
> +
> +  add_setshow_prefix_cmd ("scheduler-locking", class_run, _("\
> +Scheduler locking settings.\n\
> +Configure scheduler locking settings in various conditions."), _("\
> +Show scheduler locking settings in various conditions."),
> +			&schedlock_set_cmdlist,
> +			&schedlock_show_cmdlist,
>  			&setlist, &showlist);
>  
> +  add_setshow_boolean_cmd ("continue", class_run, &schedlock.normal.cont.value, _("\
> +Scheduler locking for continuing commands during normal execution."), _("\
> +Show scheduler locking for continuing commands during normal execution."),
> +			   _("\
> +Controls scheduler locking for continuing commands during normal execution.\n\
> +Commands include continue, until, finish.  The setting does not affect \
> +stepping."),
> +			   set_schedlock_callback,
> +			   show_schedlock_option,
> +			   &schedlock_set_cmdlist,
> +			   &schedlock_show_cmdlist);
> +
> +  add_setshow_boolean_cmd ("step", class_run, &schedlock.normal.step.value, _("\
> +Scheduler locking for stepping commands.  W/o arguments locks the scheduler \
> +for stepping."), _("\
> +Show scheduler locking for stepping commands during normal execution."), _("\
> +If argument \"on\" or \"off\", sets scheduler locking behavior for stepping\n\
> +commands only during normal execution.\n\
> +Commands include step, next, stepi, nexti."),
> +			   set_schedlock_step,
> +			   show_schedlock_option,
> +			   &schedlock_set_cmdlist,
> +			   &schedlock_show_cmdlist);
> +
> +  /* Commands for set/show scheduler-locking in replay mode.
> +     The base command adds support for the shortcut
> +       set scheduler-locking replay
> +     command.  */
> +
> +  add_setshow_prefix_cmd ("replay", class_run, _("\
> +Scheduler locking settings for replay mode.\n\
> +Configure scheduler locking in various conditions such as during continuing\n\
> +or stepping."),
> +("Show scheduler locking in replay mode."),
> +			&schedlock_set_replay_cmdlist,
> +			&schedlock_show_replay_cmdlist,
> +			&schedlock_set_cmdlist,
> +			&schedlock_show_cmdlist);
> +  add_prefix_cmd ("replay", class_run, set_schedlock_replay, _("\
> +Scheduler locking settings for replay mode. \
> +W/o arguments completely locks the scheduler in replay mode."),
> +		  &schedlock_set_replay_cmdlist,
> +	   0, &schedlock_set_cmdlist);
> +
> +  add_setshow_boolean_cmd ("continue", class_run, &schedlock.replay.cont.value, _("\
> +Set scheduler locking for continuing commands in replay mode."), _("\
> +Show scheduler locking for continuing commands in replay mode."), _("\
> +Controls scheduler locking for continuing commands in replay mode.\n\
> +Commands include continue, until, finish.  The setting does not affect \
> +stepping."),
> +			   set_schedlock_callback,
> +			   show_schedlock_option,
> +			   &schedlock_set_replay_cmdlist,
> +			   &schedlock_show_replay_cmdlist);
> +
> +  add_setshow_boolean_cmd ("step", class_run, &schedlock.replay.step.value, _("\
> +Set scheduler locking for stepping commands in replay mode."), _("\
> +Show scheduler locking for stepping commands in replay mode."), _("\
> +Controls scheduler locking for stepping commands in replay mode.\n\
> +Commands include step, next, stepi, nexti."),
> +			   set_schedlock_callback,
> +			   show_schedlock_option,
> +			   &schedlock_set_replay_cmdlist,
> +			   &schedlock_show_replay_cmdlist);
> +
> +/* Commands "set scheduler-locking on" and "set scheduler-locking off"
> +   are provided for backward compatibility.  */
> +  c = add_cmd ("on", class_run, set_schedlock_on, _("\
> +[Shortcut] Full locking (no thread except the current thread may run).\n\
> +This applies to both normal execution and replay mode."),
> +	   &schedlock_set_cmdlist);
> +
> +  c = add_cmd ("off", class_run, set_schedlock_off, _("\
> +[Shortcut] No locking (threads may preempt at any time)."),
> +	   &schedlock_set_cmdlist);
> +
>    add_setshow_boolean_cmd ("schedule-multiple", class_run, &sched_multi, _("\
>  Set mode for resuming threads of all processes."), _("\
>  Show mode for resuming threads of all processes."), _("\
> diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> index 7555469b579..b7f813320c1 100644
> --- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> +++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> @@ -257,17 +257,12 @@ proc make_cli_in_mi_re { command cli_in_mi_mode mode event inf cli_thread
>  # Return the current value of the "scheduler-locking" parameter.
>  
>  proc show_scheduler_locking { } {
> -    global gdb_prompt
> -    global expect_out
> -
> -    set any "\[^\r\n\]*"
> -
>      set test "show scheduler-locking"
> -    gdb_test_multiple $test $test {
> -	-re ".*Mode for locking scheduler during execution is \"(${any})\".\r\n$gdb_prompt " {
> -	    pass $test
> -	    return $expect_out(1,string)
> -	}
> +    set schedlock [get_scheduler_locking $test]
> +
> +    if {$schedlock ne "unknown"} {
> +	pass $test
> +	return $schedlock
>      }
>  
>      error "Couldn't get current scheduler-locking value."
> @@ -313,7 +308,7 @@ proc test_continue_to_start { mode inf } {
>  	    }
>  
>  	    if { $mode == "all-stop" } {
> -		set previous_schedlock_val [show_scheduler_locking]
> +		set previous_schedlock [show_scheduler_locking]
>  
>  		# Set scheduler-locking on, so that we can control threads
>  		# independently.
> @@ -344,7 +339,10 @@ proc test_continue_to_start { mode inf } {
>  		}
>  
>  		# Restore scheduler-locking to its original value.
> -		gdb_test_no_output "set scheduler-locking $previous_schedlock_val"
> +		foreach opt {"continue" "replay continue" "replay step" "step"} {
> +		    gdb_test_no_output \
> +			"set scheduler-locking $opt [dict get $previous_schedlock $opt]"
> +		}
>  	    } else { # $mode == "non-stop"
>  		# Put a thread-specific breakpoint for thread 2 of the current
>  		# inferior.  We don't put a breakpoint for thread 3, since we
> diff --git a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp
> index 2f5eaa5405b..75be13c4c4d 100644
> --- a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp
> +++ b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp
> @@ -68,7 +68,10 @@ gdb_test "continue" \
>  # Before we start making hand function calls, turn on scheduler locking.
>  
>  gdb_test_no_output "set scheduler-locking on" "enable scheduler locking"
> -gdb_test "show scheduler-locking" ".* locking scheduler .* is \"on\"." "show scheduler locking on"
> +set test "show scheduler-locking on"
> +gdb_assert {[get_scheduler_locking $test \
> +		 [dict create "continue" "on" "replay continue" "on" \
> +		      "replay step" "on" "step" "on"]] ne "unknown"} $test
>  
>  # Now hand-call a function in each thread, having the function
>  # stop without returning.
> @@ -139,7 +142,10 @@ gdb_test_multiple "maint print dummy-frames" "all dummies popped" {
>  
>  # Before we resume the full program, turn off scheduler locking.
>  gdb_test_no_output "set scheduler-locking off" "disable scheduler locking"
> -gdb_test "show scheduler-locking" ".* locking scheduler .* is \"off\"." "show scheduler locking off"
> +set test "show scheduler-locking off"
> +gdb_assert {[get_scheduler_locking $test \
> +		 [dict create "continue" "off" "replay continue" "off" \
> +		      "replay step" "off" "step" "off"]] ne "unknown"} $test
>  
>  # Continue one last time, the program should exit normally.
>  #
> diff --git a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp
> index fdcbaa47c7f..0a33550c65b 100644
> --- a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp
> +++ b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp
> @@ -49,8 +49,10 @@ foreach_with_prefix thread {5 4 3}  {
>  gdb_breakpoint [gdb_get_line_number "testmarker01"]
>  gdb_continue_to_breakpoint "testmarker01"
>  gdb_test_no_output "set scheduler-locking on"
> -gdb_test "show scheduler-locking" \
> -  "Mode for locking scheduler during execution is \"on\"."
> +set test "show scheduler-locking"
> +gdb_assert {[get_scheduler_locking $test \
> +		 [dict create \"continue\" \"on\" \"replay continue\" \"on\" \
> +		      \"replay step\" \"on\" \"step\" \"on\"]] ne \"unknown\"} $test
>  
>  foreach_with_prefix thread {5 4 3 2 1}  {
>    gdb_test "thread ${thread}" "Switching to .*"
> diff --git a/gdb/testsuite/gdb.threads/schedlock.exp b/gdb/testsuite/gdb.threads/schedlock.exp
> index 61a9d5ddef5..cda4585ca08 100644
> --- a/gdb/testsuite/gdb.threads/schedlock.exp
> +++ b/gdb/testsuite/gdb.threads/schedlock.exp
> @@ -94,7 +94,8 @@ proc get_current_thread { description } {
>  # Make sure we're stopped in the loop, in one of the non-main threads.
>  
>  proc goto_loop { msg } {
> -    gdb_breakpoint [concat [gdb_get_line_number "schedlock.exp: main loop"] " if arg != 0"]
> +    global srcfile
> +    gdb_breakpoint [concat "$srcfile:" [gdb_get_line_number "schedlock.exp: main loop"] " if arg != 0"]
>  
>      set test "return to loop"
>      if {$msg != ""} {
> @@ -268,16 +269,21 @@ with_test_prefix "schedlock=on: cmd=continue" {
>  }
>  
>  # Test stepping/nexting with different modes of scheduler locking.
> -proc test_step { schedlock cmd call_function } {
> +# Do scheduler-locking off setting before the test if PRESET_SCHEDLOCK_OFF is 1.
> +# LOCKED defines whether we expect the thread to be locked.  If -1, then
> +# determine it first.
> +proc test_step { schedlock cmd call_function { preset_schedlock_off 1 } { locked -1 } } {
>      global NUM
>  
> -    gdb_test_no_output "set scheduler-locking off"
> +    if {$preset_schedlock_off} {
> +	gdb_test_no_output "set scheduler-locking off"
> +    }
>      goto_loop ""
>  
>      set curthread [get_current_thread "before"]
>  
>      # No need to set to off again.  This avoids a duplicate message.
> -    if {$schedlock != "off"} {
> +    if {$preset_schedlock_off && $schedlock != "off"} {
>  	gdb_test_no_output "set scheduler-locking $schedlock"
>      }
>  
> @@ -288,16 +294,18 @@ proc test_step { schedlock cmd call_function } {
>  
>      step_ten_loops $cmd
>  
> -    if { $schedlock == "on" || $schedlock == "step" } {
> -	set locked 1
> -    } else {
> -	set locked 0
> +    if { $locked == -1 } {
> +	if { $schedlock == "on" || $schedlock == "step"} {
> +	    set locked 1
> +	} else {
> +	    set locked 0
> +	}
>      }
>  
>      check_result $cmd $curthread $before_args $locked
>  }
>  
> -# Test stepping/nexting with different modes of scheduler locking.
> +# Test stepping/nexting with different shortcut modes of scheduler locking.
>  foreach schedlock {"off" "step" "on"} {
>      with_test_prefix "schedlock=$schedlock" {
>  	with_test_prefix "cmd=step" {
> @@ -316,3 +324,57 @@ foreach schedlock {"off" "step" "on"} {
>  	}
>      }
>  }
> +
> +proc test_schedlock_opts {cont step} {
> +    set test "show scheduler-locking"
> +    if {[get_scheduler_locking $test \
> +			 [dict create "continue" $cont "replay continue" "off" \
> +				  "replay step" "off" "step" $step]] eq "unknown"} {
> +	fail $test
> +    } else {
> +	pass $test
> +    }
> +
> +    set locked 0
> +    if {$step eq "on"} {
> +	set locked 1
> +    }
> +
> +    # Stepping tests.
> +    with_test_prefix "cmd=step" {
> +	test_step "" "step" 0 0 $locked
> +    }
> +    with_test_prefix "cmd=next" {
> +	foreach call_function {0 1} {
> +	    with_test_prefix "call_function=$call_function" {
> +		test_step "" "next" $call_function 0 $locked
> +	    }
> +	}
> +    }
> +
> +    # Continuing tests.
> +    set locked 0
> +    if {$cont eq "on"} {
> +	set locked 1
> +    }
> +    with_test_prefix "cmd=continue" {
> +	# Use whichever we stopped in.
> +	set curthread [get_current_thread "before"]
> +	set cont_args [get_args "before"]
> +	my_continue "continue"
> +	check_result "continue" $curthread $cont_args $locked
> +    }
> +}
> +
> +gdb_test_no_output "set scheduler-locking off"
> +
> +# Test different options of scheduler locking.
> +foreach cont {"off" "on"} {
> +    foreach step {"off" "on"} {
> +	with_test_prefix "continue=$cont step=$step" {
> +	    gdb_test_no_output "set scheduler-locking continue $cont"
> +	    gdb_test_no_output "set scheduler-locking step $step"
> +	    test_schedlock_opts $cont $step
> +	}
> +    }
> +}
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index a40c87c6727..e852fd1b99a 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -10192,6 +10192,52 @@ gdb_caching_proc gdb_target_symbol_prefix {} {
>      return $prefix
>  }
>  
> +# Return a dictionary of scheduler locking settings with keys:
> +# continue, replay continue, replay step, step.
> +# TEST is an optional test name.
> +# EXPECTED is a dictionary of expected values for scheduler locking with
> +# the same keys.  If EXPECTED has less elements than scheduler locking
> +# settings, that means that both on and off can be expected for missing
> +# settings.
> +proc get_scheduler_locking {{test ""} {expected ""}} {
> +    global gdb_prompt
> +    if {$test eq ""} {
> +	set test "reading current scheduler-locking mode"
> +    }
> +
> +    set opts {"continue" "replay continue" "replay step" "step"}
> +
> +    # Fill the missing entries in EXPECTED list.
> +    foreach opt $opts {
> +	if {![dict exists $expected $opt]} {
> +	    dict set expected $opt "\(?:on|off\)"
> +	}
> +    }
> +
> +    set any "\[^\r\n\]+"
> +    set schedlock_regex ""
> +    foreach opt $opts {
> +	set opt_regex \
> +	    "${any}$opt: +\"\([dict get $expected $opt]\)\"${any}"
> +	set schedlock_regex "$schedlock_regex\[\r\n\]+$opt_regex"
> +    }
> +
> +    set current_schedlock_mode "unknown"
> +    gdb_test_multiple "show scheduler-locking" $test {
> +	-re -wrap $schedlock_regex {
> +	    set current_schedlock_mode [dict create]
> +	    set i 1
> +	    foreach opt $opts {
> +		dict set current_schedlock_mode $opt $expect_out($i,string)
> +		incr $i
> +	    }
> +	}
> +	-re -wrap "" {}
> +	timeout {}
> +    }
> +    return $current_schedlock_mode
> +}
> +
>  # Return 1 if target supports scheduler locking, otherwise return 0.
>  
>  gdb_caching_proc target_supports_scheduler_locking {} {
> @@ -10211,28 +10257,24 @@ gdb_caching_proc target_supports_scheduler_locking {} {
>      }
>  
>      set supports_schedule_locking -1
> -    set current_schedule_locking_mode ""
>  
>      set test "reading current scheduler-locking mode"
> -    gdb_test_multiple "show scheduler-locking" $test {
> -	-re "Mode for locking scheduler during execution is \"(\[\^\"\]*)\".*$gdb_prompt" {
> -	    set current_schedule_locking_mode $expect_out(1,string)
> -	}
> -	-re "$gdb_prompt $" {
> -	    set supports_schedule_locking 0
> -	}
> -	timeout {
> -	    set supports_schedule_locking 0
> -	}
> +    set current_schedlock [get_scheduler_locking $test]
> +    if { $current_schedlock eq "unknown" } {
> +	set supports_schedule_locking 0
>      }
>  
>      if { $supports_schedule_locking == -1 } {
>  	set test "checking for scheduler-locking support"
> -	gdb_test_multiple "set scheduler-locking $current_schedule_locking_mode" $test {
> -	    -re "Target '\[^'\]+' cannot support this command\..*$gdb_prompt $" {
> +	set regex_schedlock \
> +	    "set scheduler-locking step [dict get $current_schedlock step]"
> +
> +	# Try to set scheduler-locking run.
> +	gdb_test_multiple $regex_schedlock $test {
> +	    -re -wrap "Target '\[^'\]+' cannot support this command\..*" {
>  		set supports_schedule_locking 0
>  	    }
> -	    -re "$gdb_prompt $" {
> +	    -re -wrap "" {
>  		set supports_schedule_locking 1
>  	    }
>  	    timeout {
> -- 
> 2.34.1
>
> Intel Deutschland GmbH
>
> Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
> Tel: +49 89 991 430, www.intel.de
> Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
> Chairperson of the Supervisory Board: Nicole Lau
> Registered Seat: Munich
> Commercial Register: Amtsgericht Muenchen HRB 186928


  parent reply	other threads:[~2026-07-24  9:34 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22 10:27 [PING PATCH v8 0/6] gdb: refine scheduler locking settings Klaus Gerlicher
2026-07-22 10:27 ` [PATCH v8 1/6] gdb: use schedlock_applies in user_visible_resume_ptid Klaus Gerlicher
2026-07-22 19:05   ` Andrew Burgess
2026-07-22 10:27 ` [PATCH v8 2/6] gdb, cli: remove left-over code from "set_logging_on" Klaus Gerlicher
2026-07-22 19:13   ` Andrew Burgess
2026-07-22 10:27 ` [PATCH v8 3/6] gdb, cli: pass the argument of a set command to its callback Klaus Gerlicher
2026-07-22 20:16   ` Andrew Burgess
2026-07-23  9:06     ` Andrew Burgess
2026-07-22 10:27 ` [PATCH v8 4/6] gdb: change the internal representation of scheduler locking Klaus Gerlicher
2026-07-23 13:48   ` Andrew Burgess
2026-07-22 10:27 ` [PATCH v8 5/6] gdb: refine commands to control " Klaus Gerlicher
2026-07-23 16:39   ` Andrew Burgess
2026-07-24  9:34   ` Andrew Burgess [this message]
2026-07-22 10:27 ` [PATCH v8 6/6] gdb: add eval option to lock the scheduler during infcalls Klaus Gerlicher
2026-07-24  9:52   ` 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=87jyqkoho0.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=guinevere@redhat.com \
    --cc=klaus.gerlicher@intel.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