From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id GZ4rHsOmnmqA6jMAWB0awg (envelope-from ) for ; Mon, 07 Sep 2026 07:57:55 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gBoioH34; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 65CDA1E09E; Mon, 07 Sep 2026 07:57:55 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::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 AA4251E091 for ; Mon, 07 Sep 2026 07:57:51 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4248D4A9E065 for ; Mon, 7 Sep 2026 11:57:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4248D4A9E065 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gBoioH34 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) by sourceware.org (Postfix) with ESMTPS id 5C36548FA807 for ; Mon, 7 Sep 2026 11:56:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5C36548FA807 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 5C36548FA807 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788782163; cv=none; b=P/3GXuWaHjPf+XRn9em6LXTixGiLfbMZ8RFvns+aCeOZdeXgz3kAW0Q2fNAG1O2N73CEsWKdNp7BrZ39tA0caB+1KYGUdJjSou6Sw6wTY9Q/IMImNBHcq+qJn233O4pX0skocn1FFDhsxg4+6LJrnr+tSw0qyO6vt7jjjqsJfJQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788782163; c=relaxed/simple; bh=ydW0mmB35Ota79jzv7D7xa6rW2hiYZ6Zm9YfnVdL9Hg=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=TerTh+ypXjVEyrpOcw7Zv/418QFmWYK35W7N+bOnR30D0QUxrYXO6g+6okQwhqjgSAP0uJwjcVs4btaQTxXqQ26emhhRyXzM60BloTcVYBx0XhPlE8FoK0S2r1J++zo9sD4D9dcaV0NksRwUZauGxN40CCj5x9Z8r1ro2fuPNP8= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gBoioH34 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5C36548FA807 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1788782164; x=1820318164; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ydW0mmB35Ota79jzv7D7xa6rW2hiYZ6Zm9YfnVdL9Hg=; b=gBoioH34XBbevmesuR3VWS7lvMyQXcP3GVfT9CfPiJUwOKpxPDsvCvHC C9SweCarrAkIvEKJfEOOCFGKSfqd76smHBHEMi3pS8jcNKLEFV3X01otZ hOTfNa1HCihzATaIyYDlkujK4Ovq2xSArq2LwuQfyN/p1uoCy798IdCVw MOzXyLo2/9nc/FUUFxgkHdHEv30slioCcgpXQx4S5QACESCjavOH5Oz4f 546HE/yOCjzJvFDhSbKNJH82wztSBg5+2HWeCmh+p5Mx/AGDAV+k6/kxF 04CxLVUVisgQxQdK3j6/CDNSR2CLVlFOUqkXQPevjxLhA4/bB3M+EOvI2 w==; X-CSE-ConnectionGUID: NGVeBVTGTsiohSkx4wVozA== X-CSE-MsgGUID: FdT/5pmCQmWdXaMCBNutbQ== X-IronPort-AV: E=McAfee;i="6800,10657,11898"; a="99517588" X-IronPort-AV: E=Sophos;i="6.25,267,1779174000"; d="scan'208";a="99517588" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Sep 2026 04:56:03 -0700 X-CSE-ConnectionGUID: 1DUaP22MRE+HxhD5h6xYVQ== X-CSE-MsgGUID: GTyZYW+ZR3GwR9O2rXcXrA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,267,1779174000"; d="scan'208";a="264496086" Received: from dut1583dg2frd.igk.intel.com (HELO localhost) ([10.211.179.243]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Sep 2026 04:56:01 -0700 From: Klaus Gerlicher To: gdb-patches@sourceware.org Cc: tom@tromey.com, aburgess@redhat.com, eliz@gnu.org, guinevere@redhat.com Subject: [PATCH v9 6/6] gdb: add eval option to lock the scheduler during infcalls. Date: Mon, 7 Sep 2026 11:55:37 +0000 Message-Id: <20260907115537.307049-7-klaus.gerlicher@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260907115537.307049-1-klaus.gerlicher@intel.com> References: <20260907115537.307049-1-klaus.gerlicher@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 From: Natalia Saiapova This patch adds an "eval" scheduler locking setting to control inferior function calls separately from other continuing commands. "continue" handles continuing commands, such as continue, until, return, finish, jump. "eval" handles inferior calls. Show scheduler locking: (gdb) show scheduler-locking scheduler-locking continue: "off" Scheduler locking for continuing commands is "off" during normal execution. scheduler-locking eval: "off" Scheduler locking for function calls is "off" during normal execution. scheduler-locking replay continue: "on" Scheduler locking for continuing commands is "on" during replay mode. scheduler-locking replay eval: "on" Scheduler locking for function calls 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. Reviewed-By: Eli Zaretskii --- gdb/NEWS | 21 +++-- gdb/doc/gdb.texinfo | 37 ++++++-- gdb/infrun.c | 73 +++++++++++++--- .../gdb.mi/user-selected-context-sync.exp | 29 ++++--- .../gdb.threads/hand-call-in-threads.exp | 8 +- .../multiple-successive-infcall.exp | 3 +- gdb/testsuite/gdb.threads/schedlock.c | 3 +- gdb/testsuite/gdb.threads/schedlock.exp | 86 +++++++++++++------ gdb/testsuite/lib/gdb.exp | 2 +- 9 files changed, 194 insertions(+), 68 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 09926ae0b2e..4e59eb5e8a4 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -931,19 +931,28 @@ list . 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, + continue | eval | replay continue | replay eval | 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, + continuing and evaluating commands. Stepping commands include step, stepi, next. Continuing commands include continue, finish, until, jump, return. + The evaluating commands are those which invoke inferior calls, such as + direct user calls (e.g., 'print some_func()') and other inferior calls + triggered by GDB (e.g., Python pretty-printers, display expressions). + Note: Breakpoint and watchpoint condition evaluation always runs on the + thread that triggered the breakpoint, regardless of the 'eval' setting. 'continue' -- when on, the scheduler is locked during continuing commands - during normal execution (not replay mode). + outside replay mode. + 'eval' -- when on, the scheduler is locked during inferior calls + outside replay mode. 'replay continue' -- when on, the scheduler is locked during continuing commands in replay mode. + 'replay eval' -- when on, the scheduler is locked during inferior calls + 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 - during normal execution (not replay mode). + outside replay 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 diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 7767c399fa4..56005144149 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -7462,10 +7462,14 @@ locking the OS scheduler to allow only a single thread to run. @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. +for stepping commands, continuing commands, and inferior function calls. +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}. +Inferior function calls include direct user calls (e.g., @code{print func()}) +and calls triggered by @value{GDBN} such as @code{display} expressions. +Breakpoint and watchpoint condition evaluation always runs on the thread +that triggered the breakpoint and is not affected by these settings. The following @var{type}-settings are available. When a setting is @samp{on}, the scheduler is locked: other threads may not preempt the @@ -7476,10 +7480,25 @@ current thread, so that the focus of debugging does not change unexpectedly. Applies to continuing commands during normal execution and record modes. This setting is @samp{off} by default. +@item eval +When @samp{on}, the scheduler is locked during inferior calls in normal +execution mode, such that other threads may not preempt the current thread. +This applies to direct user calls (e.g., @code{print some_func()}) and +other inferior calls triggered by @value{GDBN} such as Python +pretty-printers and @code{display} expressions. +This setting is @samp{off} by default. +Note: Breakpoint and watchpoint condition evaluation always runs on the +thread that triggered the breakpoint, regardless of this setting. + @item replay continue Applies to continuing commands during replay mode. This setting is @samp{on} by default. +@item replay eval +When @samp{on}, the scheduler is locked during inferior calls in replay +mode, such that other threads may not preempt the current thread. +This setting is @samp{on} by default. + @item replay step Applies to stepping commands during replay mode. This setting is @samp{on} by default. @@ -7509,7 +7528,7 @@ they execute any instruction. This is equivalent to setting all type options to @samp{on}. @item step -Behaves like @code{on} when stepping, and @code{off} otherwise. +Behaves like @samp{on} when stepping, and @samp{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 continuing commands. @@ -7526,12 +7545,12 @@ This is equivalent to setting @samp{scheduler-locking step} and are @samp{off}. @item replay -Behaves like @code{on} in replay mode, and @code{off} in either record +Behaves like @samp{on} in replay mode, and @samp{off} in either record mode or during normal execution. This is the default mode. -This is equivalent to setting @samp{scheduler-locking replay continue} and -@samp{scheduler-locking replay step} to @samp{on}, while other settings -are @samp{off}. +This is equivalent to setting @samp{scheduler-locking replay continue}, +@samp{scheduler-locking replay eval} and @samp{scheduler-locking replay step} +to @samp{on}, while other settings are @samp{off}. @end table diff --git a/gdb/infrun.c b/gdb/infrun.c index 327ab12fbba..f190fef50b0 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -112,9 +112,9 @@ struct schedlock_mode_options; static bool schedlock_applies (thread_info *tp); static bool schedlock_applies (bool step, bool record_will_replay, - thread_info *tp = nullptr); + thread_info *tp); static bool schedlock_applies_to_opts (const schedlock_mode_options &, - bool step); + bool step, thread_info *tp); static void handle_process_exited (struct execution_control_state *ecs); @@ -2458,14 +2458,17 @@ schedlock_option::set (bool new_value) struct schedlock_mode_options { schedlock_mode_options () = delete; - schedlock_mode_options (schedlock_option cont, schedlock_option step) - : cont (std::move (cont)), step (std::move (step)) + schedlock_mode_options (schedlock_option eval, schedlock_option cont, + schedlock_option step) + : eval (std::move (eval)), cont (std::move (cont)), step (std::move (step)) {} DISABLE_COPY_AND_ASSIGN (schedlock_mode_options); schedlock_mode_options (schedlock_mode_options &&) = default; schedlock_mode_options &operator= (schedlock_mode_options &&) = default; + /* If true, the scheduler is locked during inferior calls. */ + schedlock_option eval; /* If true, the scheduler is locked during continuing. */ schedlock_option cont; /* If true, the scheduler is locked during stepping. */ @@ -2492,10 +2495,12 @@ static const char schedlock_replay[] = "replay"; /* Global scheduler locking state. */ static schedlock_state scheduler_locking_state { { + {"eval", false}, {"cont", false}, {"step", false} }, { + {"replay eval", true}, {"replay cont", true}, {"replay step", true} } @@ -2519,9 +2524,11 @@ set_schedlock_shortcut_option (const char *shortcut) bool any_changed = scheduler_locking_state.normal.cont.set (is_on); any_changed = scheduler_locking_state.normal.step.set (is_on || is_step) || any_changed; + any_changed = scheduler_locking_state.normal.eval.set (is_on) || any_changed; any_changed = scheduler_locking_state.replay.cont.set (is_on || is_replay) || any_changed; any_changed = scheduler_locking_state.replay.step.set (is_on || is_replay || is_step) || any_changed; + any_changed = scheduler_locking_state.replay.eval.set (is_on || is_replay) || any_changed; /* If at least one parameter has changed, notify the observer in the old-fashioned way. */ @@ -2603,6 +2610,15 @@ show_schedlock_option (ui_file *file, int from_tty, gdb_printf (file, _("Scheduler locking for continuing commands " "in normal execution is \"%s\".\n"), value); } + else if (strcmp (c->name, "eval") == 0) + { + if (is_replay) + gdb_printf (file, _("Scheduler locking for function calls " + "in replay mode is \"%s\".\n"), value); + else + gdb_printf (file, _("Scheduler locking for function calls " + "in normal execution is \"%s\".\n"), value); + } else gdb_assert_not_reached ("Unexpected command name."); } @@ -3373,9 +3389,13 @@ clear_proceed_status (int step, bool about_to_proceed) but also for "set scheduler-locking on" and (when stepping) "set scheduler-locking step". This ensures that when any form of scheduler locking is active that would affect replay mode, we stop - replaying threads that have finished their replay. */ + replaying threads that have finished their replay. + + Pass nullptr for the thread_info because clear_proceed_status runs + before any specific thread has been selected for execution, so + there is no meaningful infcall state to check. */ if (!non_stop && schedlock_applies_to_opts (scheduler_locking_state.replay, - step) + step, nullptr) && !target_record_will_replay (inferior_ptid, execution_direction)) target_record_stop_replaying (); @@ -3455,13 +3475,32 @@ thread_still_needs_step_over (struct thread_info *tp) /* Return true if OPTS lock the scheduler. STEP indicates whether a thread is about to step. + While the stepping info we take from STEP argument, the inferior call + state we get from the thread TP. TP may be nullptr, in which case the + scheduler is treated as not being in an inferior call. This function does not take into account the mode (replay or - normal execution). */ + normal execution). + + Note: When stepping during an inferior call (e.g., evaluating a + conditional breakpoint's condition that calls a function during a step + command), both the 'step' and 'eval' settings are checked independently. + The scheduler is locked if either setting is on. The 'cont' setting is + excluded during inferior calls; those are handled by the 'eval' + setting. */ static bool -schedlock_applies_to_opts (const schedlock_mode_options &opts, bool step) +schedlock_applies_to_opts (const schedlock_mode_options &opts, bool step, + thread_info *tp) { - return ((opts.cont && !step) || (opts.step && step)); + bool in_infcall = (tp != nullptr) && tp->control.in_infcall; + + return (opts.cont && !step && !in_infcall) + /* Intentionally no in_infcall check here: step protection + applies even during inferior calls. Both step and eval + settings are checked independently; scheduler is locked if + either is on. */ + || (opts.step && step) + || (opts.eval && in_infcall); } /* Returns true if scheduler locking applies to non-NULL thread TP. */ @@ -3486,7 +3525,7 @@ schedlock_applies (bool step, bool record_will_replay, thread_info *tp) schedlock_mode_options &opts = record_will_replay ? scheduler_locking_state.replay : scheduler_locking_state.normal; - return schedlock_applies_to_opts (opts, step); + return schedlock_applies_to_opts (opts, step, tp); } /* When FORCE_P is false, set process_stratum_target::COMMIT_RESUMED_STATE @@ -11144,6 +11183,13 @@ Commands include step, next, stepi, nexti."), set_schedlock_step, &schedlock_set_cmdlist, &schedlock_show_cmdlist); + scheduler_locking_state.normal.eval.make_cli_option + ("eval", + _("Scheduler locking for function calls during normal execution."), + _("Show scheduler locking for function calls during normal execution."), + _("Controls scheduler locking for function calls during normal execution."), + &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 @@ -11181,6 +11227,13 @@ stepping and function calls."), Commands include step, next, stepi, nexti."), &schedlock_set_replay_cmdlist, &schedlock_show_replay_cmdlist); + scheduler_locking_state.replay.eval.make_cli_option + ("eval", + _("Set scheduler locking for function calls in replay mode."), + _("Show scheduler locking for function calls in replay mode."), + _("Controls scheduler locking for function calls in replay mode."), + &schedlock_set_replay_cmdlist, &schedlock_show_replay_cmdlist); + /* Commands "set scheduler-locking on" and "set scheduler-locking off" are provided for backward compatibility. */ add_cmd ("on", class_run, set_schedlock_on, _("\ diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp index 7555469b579..9cb132d1c47 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,17 @@ 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" "eval" "replay continue" \ + "replay eval" "replay step" "step"} { + gdb_test_no_output \ + "set scheduler-locking $opt [dict get $previous_schedlock $opt]" + } + + # Verify the restore above actually put every sub-option back + # to what it was, not just the "continue" one. + set test "scheduler-locking restored to previous value" + gdb_assert {[get_scheduler_locking $test $previous_schedlock] \ + ne "unknown"} $test } 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 06ec22e1138..1f7d5c8e937 100644 --- a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp +++ b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp @@ -70,8 +70,8 @@ gdb_test "continue" \ gdb_test_no_output "set scheduler-locking on" "enable scheduler locking" set test "show scheduler-locking on" gdb_assert {[get_scheduler_locking $test \ - [dict create "continue" "on" \ - "replay continue" "on" \ + [dict create "continue" "on" "eval" "on" \ + "replay continue" "on" "replay eval" "on" \ "replay step" "on" "step" "on"]] ne "unknown"} $test # Now hand-call a function in each thread, having the function @@ -145,8 +145,8 @@ gdb_test_multiple "maint print dummy-frames" "all dummies popped" { gdb_test_no_output "set scheduler-locking off" "disable scheduler locking" set test "show scheduler-locking off" gdb_assert {[get_scheduler_locking $test \ - [dict create "continue" "off" \ - "replay continue" "off" \ + [dict create "continue" "off" "eval" "off" \ + "replay continue" "off" "replay eval" "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 4bda757027b..98e50c92713 100644 --- a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp +++ b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp @@ -51,7 +51,8 @@ gdb_continue_to_breakpoint "testmarker01" gdb_test_no_output "set scheduler-locking on" set test "show scheduler-locking" gdb_assert {[get_scheduler_locking $test \ - [dict create "continue" "on" "replay continue" "on" \ + [dict create "continue" "on" "eval" "on" \ + "replay continue" "on" "replay eval" "on" \ "replay step" "on" "step" "on"]] ne "unknown"} $test foreach_with_prefix thread {5 4 3 2 1} { diff --git a/gdb/testsuite/gdb.threads/schedlock.c b/gdb/testsuite/gdb.threads/schedlock.c index d1dd91ba4ce..afab01b1d7e 100644 --- a/gdb/testsuite/gdb.threads/schedlock.c +++ b/gdb/testsuite/gdb.threads/schedlock.c @@ -50,12 +50,13 @@ int main() { exit(EXIT_SUCCESS); } -void some_function (void) { +int some_function (void) { /* Sleep a bit to give the other threads a chance to run, if not locked. This also ensure that even if the compiler optimizes out or inlines some_function, there's still be some function that needs to be stepped over. */ usleep (1); + return 1; } /* When testing "next", this is set to have the loop call diff --git a/gdb/testsuite/gdb.threads/schedlock.exp b/gdb/testsuite/gdb.threads/schedlock.exp index 5fd52acbf91..3c17a9dbcbc 100644 --- a/gdb/testsuite/gdb.threads/schedlock.exp +++ b/gdb/testsuite/gdb.threads/schedlock.exp @@ -227,7 +227,7 @@ proc check_result { cmd before_thread before_args locked } { set num_other_threads 0 for {set i 0} {$i < $NUM} {incr i} { if {[lindex $before_args $i] == [lindex $after_args $i]} { - if {$i == $before_thread} { + if {$i == $before_thread && $cmd ne "infcall"} { fail "$test (didn't run)" } } else { @@ -325,15 +325,16 @@ foreach schedlock {"off" "step" "on"} { } # Test scheduler locking with specific option values. -# CONT and STEP are the expected values ("on" or "off") for the -# normal execution scheduler-locking options: continue and step. +# CONT, EVAL, and STEP are the expected values ("on" or "off") for the +# normal execution scheduler-locking options: continue, eval, and step. # This proc verifies the options are set correctly, then runs stepping # and continuing tests to ensure the locking behavior matches expectations. # Replay options are assumed to be "off" for these tests. -proc test_schedlock_opts {cont step} { +proc test_schedlock_opts {cont eval step} { set test "show scheduler-locking" gdb_assert {[get_scheduler_locking $test \ - [dict create "continue" $cont "replay continue" "off" \ + [dict create "continue" $cont "eval" $eval \ + "replay continue" "off" "replay eval" "off" \ "replay step" "off" "step" $step]] ne "unknown"} $test set locked 0 @@ -365,6 +366,25 @@ proc test_schedlock_opts {cont step} { my_continue "continue" check_result "continue" $curthread $cont_args $locked } + + # Infcall tests. + set locked 0 + if {$eval eq "on"} { + set locked 1 + } + with_test_prefix "cmd=infcall" { + # Use whichever we stopped in. + set curthread [get_current_thread "before-infcall"] + set cont_args [get_args "before-infcall"] + + for { set i 0 } { $i < 10 } { incr i } { + with_test_prefix "infcall #$i" { + gdb_test "print some_function()" ".*" + } + } + + check_result "infcall" $curthread $cont_args $locked + } } # Test different options of scheduler locking. @@ -372,11 +392,14 @@ with_test_prefix "option combinations" { gdb_test_no_output "set scheduler-locking off" 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 + foreach eval {"off" "on"} { + foreach step {"off" "on"} { + with_test_prefix "continue=$cont eval=$eval step=$step" { + gdb_test_no_output "set scheduler-locking continue $cont" + gdb_test_no_output "set scheduler-locking eval $eval" + gdb_test_no_output "set scheduler-locking step $step" + test_schedlock_opts $cont $eval $step + } } } } @@ -386,16 +409,20 @@ with_test_prefix "option combinations" { with_test_prefix "replay options" { gdb_test_no_output "set scheduler-locking off" foreach replay_cont {"off" "on"} { - foreach replay_step {"off" "on"} { - with_test_prefix "replay: continue=$replay_cont step=$replay_step" { - gdb_test_no_output "set scheduler-locking replay continue $replay_cont" - gdb_test_no_output "set scheduler-locking replay step $replay_step" - set test "verify replay options" - gdb_assert {[get_scheduler_locking $test \ - [dict create "continue" "off" \ - "replay continue" $replay_cont \ - "replay step" $replay_step \ - "step" "off"]] ne "unknown"} $test + foreach replay_eval {"off" "on"} { + foreach replay_step {"off" "on"} { + with_test_prefix "replay: continue=$replay_cont eval=$replay_eval step=$replay_step" { + gdb_test_no_output "set scheduler-locking replay continue $replay_cont" + gdb_test_no_output "set scheduler-locking replay eval $replay_eval" + gdb_test_no_output "set scheduler-locking replay step $replay_step" + set test "verify replay options" + gdb_assert {[get_scheduler_locking $test \ + [dict create "continue" "off" "eval" "off" \ + "replay continue" $replay_cont \ + "replay eval" $replay_eval \ + "replay step" $replay_step \ + "step" "off"]] ne "unknown"} $test + } } } } @@ -407,17 +434,28 @@ with_test_prefix "individual options" { # Test setting only 'continue'. gdb_test_no_output "set scheduler-locking continue on" gdb_assert {[get_scheduler_locking "continue only" \ - [dict create "continue" "on" \ - "replay continue" "off" \ + [dict create "continue" "on" "eval" "off" \ + "replay continue" "off" "replay eval" "off" \ "replay step" "off" "step" "off"]] ne "unknown"} \ "continue only" + # Reset and test setting only 'eval'. + gdb_test_no_output "set scheduler-locking off" + gdb_test_no_output "set scheduler-locking eval on" + gdb_assert {[get_scheduler_locking "eval only" \ + [dict create "continue" "off" "eval" "on" \ + "replay continue" "off" "replay eval" "off" \ + "replay step" "off" "step" "off"]] ne "unknown"} \ + "eval only" + # Reset and test setting only 'step'. gdb_test_no_output "set scheduler-locking off" "reset for step test" gdb_test_no_output "set scheduler-locking step on" gdb_assert {[get_scheduler_locking "step only" \ - [dict create "continue" "off" \ - "replay continue" "off" \ + [dict create "continue" "off" "eval" "off" \ + "replay continue" "off" "replay eval" "off" \ "replay step" "off" "step" "on"]] ne "unknown"} \ "step only" } + + diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 7de75265513..cf7f98e2918 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -10437,7 +10437,7 @@ proc get_scheduler_locking {{test ""} {expected ""}} { set test "reading current scheduler-locking mode" } - set opts {"continue" "replay continue" "replay step" "step"} + set opts {"continue" "eval" "replay continue" "replay eval" "replay step" "step"} # Fill the missing entries in EXPECTED list. foreach opt $opts { -- 2.34.1 ________________________________________ Intel Deutschland GmbH Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany Tel: +49 (89) 99143-0 www.intel.de Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman Chairperson of the Supervisory Board: Sonja Pierer Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.