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
next prev 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