@@ -815,15 +815,20 @@ list .
set scheduler-locking <command type> (on|off)
show scheduler-locking <command type>
where <command-type> 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.
'continue' -- when on, the scheduler is locked during continuing commands
in normal mode.
+ 'eval' -- when on, the scheduler is locked during inferior calls in
+ normal 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
@@ -7419,10 +7419,10 @@ 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 continuing and stepping commands, as well as 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}.
The following @var{type}-settings are available. When a setting is
@code{on}, the scheduler is locked: other threads may not preempt the
@@ -7433,10 +7433,21 @@ 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 @code{off} by default.
+@item eval
+When @code{on}, the scheduler is locked for function calls during normal
+execution and record modes, such that other threads may not preempt
+the current thread during the inferior call. 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 eval
+When @code{on}, the scheduler is locked for function calls during replay
+mode, such that other threads may not preempt the current thread during
+the inferior call. This setting is @code{on} by default.
+
@item replay step
Applies to stepping commands during replay mode. This setting is
@code{on} by default.
@@ -7486,9 +7497,9 @@ are @code{off}.
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}.
+This is equivalent to set @samp{scheduler-locking replay continue},
+@samp{scheduler-locking replay eval} and @samp{scheduler-locking replay step}
+to @code{on}, while other settings are @code{off}.
@end table
@@ -114,7 +114,9 @@ static bool schedlock_applies (thread_info *tp);
static bool schedlock_applies (bool step,
bool record_will_replay,
thread_info *tp = nullptr);
-static bool schedlock_applies_to_opts (const schedlock_options &, bool step);
+static bool schedlock_applies_to_opts (const schedlock_options &,
+ bool step,
+ thread_info *tp = nullptr);
/* Command lists for the scheduler locking. */
static cmd_list_element *schedlock_set_cmdlist;
@@ -2361,8 +2363,8 @@ struct schedlock_options
};
schedlock_options () = delete;
- schedlock_options (option cont, option step)
- : cont (std::move (cont)), step (std::move (step))
+ schedlock_options (option eval, option cont, option step)
+ : eval (std::move (eval)), cont (std::move (cont)), step (std::move (step))
{}
/* Forbid accidential copying. */
@@ -2371,6 +2373,8 @@ struct schedlock_options
schedlock_options (schedlock_options &&) = default;
schedlock_options &operator= (schedlock_options &&) = default;
+ /* If true, the scheduler is locked during inferior calls. */
+ option eval;
/* If true, the scheduler is locked during continuing. */
option cont;
/* If true, the scheduler is locked during stepping. */
@@ -2409,10 +2413,12 @@ static const char schedlock_replay[] = "replay";
schedlock schedlock {
{
+ {"eval", false},
{"cont", false},
{"step", false}
},
{
+ {"replay eval", true},
{"replay cont", true},
{"replay step", true}
}
@@ -2436,9 +2442,11 @@ set_schedlock_shortcut_option (const char *shortcut)
bool any_changed = schedlock.normal.cont.set (is_on);
any_changed = schedlock.normal.step.set (is_on || is_step) || any_changed;
+ any_changed = schedlock.normal.eval.set (is_on) || 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;
+ any_changed = schedlock.replay.eval.set (is_on || is_replay) || any_changed;
/* If at least one parameter has changed, notify the observer
in the old-fashioned way. */
@@ -2512,11 +2520,13 @@ show_schedlock_option (ui_file *file, int from_tty,
type = "stepping commands";
else if (strcmp (c->name, "continue") == 0)
type = "continuing commands";
+ else if (strcmp (c->name, "eval") == 0)
+ type = "function calls";
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);
+ "\"%s\" during %s.\n"), value, type, value, mode);
}
/* True if execution commands resume all threads of all processes by
@@ -3357,13 +3367,20 @@ 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.
Note, this does not take into the account the mode (replay or
normal execution). */
static bool
-schedlock_applies_to_opts (const schedlock_options &opts, bool step)
+schedlock_applies_to_opts (const schedlock_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)
+ || (opts.step && step)
+ || (opts.eval && in_infcall));
}
/* Returns true if scheduler locking applies to TP. */
@@ -3391,7 +3408,7 @@ schedlock_applies (bool step, bool record_will_replay, thread_info *tp)
{
schedlock_options &opts
= record_will_replay ? schedlock.replay : schedlock.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
@@ -10968,11 +10985,10 @@ Show scheduler locking settings in various conditions."),
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."),
- _("\
+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."),
+Commands include continue, until, finish. The setting does not affect\n\
+stepping and function calls."),
set_schedlock_callback,
show_schedlock_option,
&schedlock_set_cmdlist,
@@ -10990,6 +11006,16 @@ Commands include step, next, stepi, nexti."),
&schedlock_set_cmdlist,
&schedlock_show_cmdlist);
+ add_setshow_boolean_cmd ("eval", class_run, &schedlock.normal.eval.value, _("\
+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."),
+ set_schedlock_callback,
+ 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
@@ -11014,8 +11040,8 @@ W/o arguments completely locks the scheduler in replay mode."),
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."),
+Commands include continue, until, finish. The setting does not affect\n\
+stepping and function calls."),
set_schedlock_callback,
show_schedlock_option,
&schedlock_set_replay_cmdlist,
@@ -11031,6 +11057,15 @@ Commands include step, next, stepi, nexti."),
&schedlock_set_replay_cmdlist,
&schedlock_show_replay_cmdlist);
+ add_setshow_boolean_cmd ("eval", class_run, &schedlock.replay.eval.value, _("\
+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."),
+ 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, _("\
@@ -339,7 +339,8 @@ proc test_continue_to_start { mode inf } {
}
# Restore scheduler-locking to its original value.
- foreach opt {"continue" "replay continue" "replay step" "step"} {
+ foreach opt {"continue" "eval" "replay continue" \
+ "replay eval" "replay step" "step"} {
gdb_test_no_output \
"set scheduler-locking $opt [dict get $previous_schedlock $opt]"
}
@@ -70,7 +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
@@ -144,7 +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.
@@ -51,8 +51,9 @@ 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\" \
- \"replay step\" \"on\" \"step\" \"on\"]] ne \"unknown\"} $test
+ [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} {
gdb_test "thread ${thread}" "Switching to .*"
@@ -228,7 +228,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 {
@@ -321,11 +321,12 @@ foreach schedlock {"off" "step" "on"} {
}
}
-proc test_schedlock_opts {cont step} {
+proc test_schedlock_opts {cont eval 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"} {
+ [dict create "continue" $cont "eval" $eval \
+ "replay continue" "off" "replay eval" "off" \
+ "replay step" "off" "step" $step]] eq "unknown"} {
fail $test
} else {
pass $test
@@ -360,17 +361,39 @@ 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} {[expr $i < 10]} {set i [expr $i + 1]} {
+ with_test_prefix "infcall #$i" {
+ gdb_test "print some_function()" ".*"
+ }
+ }
+
+ check_result "infcall" $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
+ 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
+ }
}
}
}
@@ -9896,7 +9896,8 @@ 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 {