From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id QY70MotMg2l6ICgAWB0awg (envelope-from ) for ; Wed, 04 Feb 2026 08:41:31 -0500 Authentication-Results: simark.ca; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=f7jOXeMB; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id CBF031E08D; Wed, 04 Feb 2026 08:41:31 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_INVALID,DKIM_SIGNED,HTML_MESSAGE,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED,RDNS_NONE autolearn=no autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (unknown [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 31A7E1E08D for ; Wed, 04 Feb 2026 08:41:30 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id AEF324BA2E18 for ; Wed, 4 Feb 2026 13:41:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AEF324BA2E18 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=f7jOXeMB Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by sourceware.org (Postfix) with ESMTPS id 484864BA2E0C for ; Wed, 4 Feb 2026 13:38:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 484864BA2E0C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 484864BA2E0C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=198.175.65.12 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770212321; cv=none; b=BGPiyAkRjn6UsbTXZKybHBCatZaY6XyP5iWYQXaQNoQEaLPa35Ddz5u3XYqBoPbAJsq0BJ1PQNszLJC65awN41RcRZgxanAQp+rVn8LlLfNLqyp1cET8ZXrWCvTw2pO1+rTfAP731o8lAd81B/PmeAuFIsOeUP3lemoG140K3Qk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770212321; c=relaxed/simple; bh=tvmK7SHJCO98LHVeqOLP7c+EkYaCiHn4U4faACuO8nI=; h=DKIM-Signature:MIME-Version:From:To:Subject:Date:Message-Id: MIME-Version; b=c+K2vIIKJvhEv/L/nMPa7OyfeTsgZvd57oBUscDqWUCL7pxjpnPAau4wv6IALi5sRnHUx1HfmvDO+QZtaEUYlNLIVf/K/YBShAJ7nNIHdRv9CqJ9MCQEuQPU3lJpQKL4QxTqn/HHy7pGS7NyBP4mfjzWDX9RvmhR2vj0snVMQjc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 484864BA2E0C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1770212321; x=1801748321; h=from:to:subject:date:message-id:in-reply-to:references; bh=tvmK7SHJCO98LHVeqOLP7c+EkYaCiHn4U4faACuO8nI=; b=f7jOXeMBqhqbIqhRPQC9cWTzEUIJONPj+EUAvhsQe8nJS1ScHzrCfpWd yBARbElPDuloTLsIckhuEQhQxXRUMnFnrww9KvwxUHGXyKsir9k45H6QF xn3EU1YUlUYSi3EoiiOKT3aYC/gta+kVZFpmAGBXW0vH99LUWz11Mc9WU 22w+nMphPatb3Im0C7kGcHWWog7g52u+Tb8QM4VKTU9W2WYuMQyRHhuAO bEpptrdU2FB8VhWfWD9YSNdXL0eAmLwOgMmAoSad+sgVwA2vFkossWbNG Vgvvrz74O8M4BCLJw6ztaz4fx6coXuD/E/xNhRzIUQAClc8qH/8x052fd g==; X-CSE-ConnectionGUID: eOeKMkQPT1GQEs7VYZb4PQ== X-CSE-MsgGUID: LkvwTp4FSSWwE6riJ2aS0g== X-IronPort-AV: E=McAfee;i="6800,10657,11691"; a="82831931" X-IronPort-AV: E=Sophos;i="6.21,272,1763452800"; d="scan'208";a="82831931" Content-Type: multipart/mixed; boundary="===============0875176334700605595==" MIME-Version: 1.0 Received: from orviesa010.jf.intel.com ([10.64.159.150]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Feb 2026 05:38:41 -0800 X-CSE-ConnectionGUID: +lXEZjHsRjKxvyp9neBisA== X-CSE-MsgGUID: fyJF2bUkRoS9+rV2lxVTdw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,272,1763452800"; d="scan'208";a="209460516" Received: from dut1865dg2frd.igk.intel.com (HELO localhost) ([10.211.179.243]) by orviesa010-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Feb 2026 05:38:41 -0800 From: Klaus Gerlicher To: gdb-patches@sourceware.org Subject: [PATCH v6 5/6] gdb: refine commands to control scheduler locking. Date: Wed, 4 Feb 2026 13:37:52 +0000 Message-Id: <20260204133753.547281-6-klaus.gerlicher@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260204133753.547281-1-klaus.gerlicher@intel.com> References: <20260204133753.547281-1-klaus.gerlicher@intel.com> MIME-Version: 1.0 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org --===============0875176334700605595== Content-Transfer-Encoding: 8bit From: Natalia Saiapova 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 show scheduler-locking 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 --- 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 fa6e7ca6121..8514158c1d8 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -749,6 +749,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 (on|off) +show scheduler-locking + where is one of the following: + 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 c6a805b3ea0..6d5d07b7e77 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -7407,28 +7407,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 @@ -7437,9 +7472,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 @@ -34576,7 +34620,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 f449b222fc3..3ac669729b3 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 #include "finish-thread-state.h" /* Prototypes for local functions */ @@ -113,6 +115,12 @@ static bool schedlock_applies (bool step, thread_info *tp = nullptr); static bool schedlock_applies_to_opts (const schedlock_options &, bool step); +/* 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; @@ -2346,7 +2354,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); }; @@ -2373,6 +2382,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; } @@ -2393,15 +2405,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 { { @@ -2430,35 +2433,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 @@ -8545,15 +8602,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; @@ -10912,21 +10961,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 844206f7511..dec7ff1fde6 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 f2d93cedfed..a06f17fd253 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 732793010ef..0f25e8aeda4 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 3f3da91947a..bc6674b2781 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 != ""} { @@ -264,16 +265,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" } @@ -284,16 +290,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" { @@ -312,3 +320,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 0663f55013d..9762aec9221 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -9868,6 +9868,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 {} { @@ -9887,28 +9933,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 --===============0875176334700605595== Content-Type: multipart/alternative; boundary="===============0025172562059172385==" MIME-Version: 1.0 Content-Disposition: inline --===============0025172562059172385== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Intel Deutschland GmbH Registered Address: Dornacher Stra=C3=9Fe 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 M=C3=BCnchen HRB 186928 --===============0025172562059172385== Content-Type: text/html; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable

Intel Deutschland GmbH

Registered Ad= dress: Dornacher Stra=C3=9Fe 1, 85622 Feldkirchen, Germany
Tel: +49 89 = 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneide= rman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole La= u
Registered Seat: Munich
Commercial Register: Amtsgericht M=C3=BCn= chen HRB 186928

--===============0025172562059172385==-- --===============0875176334700605595==--