@@ -712,15 +712,20 @@ list .
set scheduler-locking <command type> (on|off)
show scheduler-locking <command type>
where <command-type> is one of the following:
- non-step | replay non-step | 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 non-stepping commands. Stepping commands include step, stepi, next.
- Non-stepping commands include continue, finish, until, jump, return.
- 'non-step' -- when on, the scheduler is locked during non-stepping commands
+ 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.
- 'replay non-step' -- when on, the scheduler is locked during non-stepping
+ '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
@@ -7387,35 +7387,47 @@ 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 non-stepping commands. Examples of stepping commands are:
-@samp{step}, @samp{stepi}, @samp{next}. Examples of non-stepping 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:
@table @code
-@item non-step
-When @code{on}, the scheduler is locked for non-stepping commands during
-normal execution and record modes. For non-stepping commands other threads
+@item continue
+When @code{on}, the scheduler is locked for continuing commands during
+normal execution and record modes. For continuing commands other threads
may not preempt the current thread. This setting is @code{off} by default.
-@item replay non-step
-When @code{on}, the scheduler is locked for non-stepping commands during
-replay mode. For non-stepping commands other threads may not preempt
+@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
+When @code{on}, the scheduler is locked for continuing commands during
+replay mode. For continuing commands other threads may not preempt
the current thread. 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
When @code{on}, the scheduler is locked for stepping commands during replay
mode. While stepping, other threads may not preempt the current thread,
so that the focus of debugging does not change unexpectedly. This setting
-is @code{on} by default.
+is @code{on} by default. This setting is @code{on} by default.
@item step
When @code{on}, the scheduler is locked for stepping commands during
normal execution and record modes. While stepping, other threads may not
preempt the current thread, so that the focus of debugging does not change
-unexpectedly. This setting is @code{off} by default.
+unexpectedly. This setting is @code{off} by default. This setting is
+@code{off} by default.
@end table
@@ -7458,9 +7470,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 non-step} 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
@@ -109,9 +109,12 @@ static bool step_over_info_valid_p (void);
struct schedlock_options;
static bool schedlock_applies (thread_info *tp);
-static bool schedlock_applies (thread_info *tp, bool step,
- bool record_will_replay);
-static bool schedlock_applies_to_opts (const schedlock_options &, bool step);
+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,
+ thread_info *tp = nullptr);
/* Command lists for the scheduler locking. */
static cmd_list_element *schedlock_set_cmdlist;
@@ -2358,8 +2361,8 @@ struct schedlock_options
};
schedlock_options () = delete;
- schedlock_options (option non_step , option step)
- : non_step (std::move (non_step )), 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. */
@@ -2368,8 +2371,10 @@ struct schedlock_options
schedlock_options (schedlock_options &&) = default;
schedlock_options &operator= (schedlock_options &&) = default;
- /* If true, the scheduler is locked during non-stepping. */
- option non_step;
+ /* 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. */
option step;
};
@@ -2404,8 +2409,18 @@ static const char schedlock_on[] = "on";
static const char schedlock_step[] = "step";
static const char schedlock_replay[] = "replay";
-schedlock schedlock {{{"non-step", false}, {"step", false}},
- {{"replay non-step", true}, {"replay step", true}}};
+schedlock schedlock {
+ {
+ {"eval", false},
+ {"cont", false},
+ {"step", false}
+ },
+ {
+ {"replay eval", true},
+ {"replay cont", true},
+ {"replay step", true}
+ }
+};
/* A helper function to set scheduler locking shortcuts:
set scheduler-locking on: all options are on.
@@ -2423,11 +2438,13 @@ 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);
- bool any_changed = schedlock.normal.non_step.set (is_on);
+ 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.non_step.set (is_on || is_replay) || 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. */
@@ -2499,8 +2516,10 @@ show_schedlock_option (ui_file *file, int from_tty,
const char *type;
if (strcmp (c->name, "step") == 0)
type = "stepping commands";
- else if (strcmp (c->name, "non-step") == 0)
- type = "non-stepping commands";
+ else if (strcmp (c->name, "continue") == 0)
+ type = "continuing commands";
+ else if (strcmp (c->name, "eval") == 0)
+ type = "expression evaluation";
else
gdb_assert_not_reached ("Unexpected command name.");
@@ -2549,8 +2568,9 @@ user_visible_resume_ptid (int step)
}
else if
(schedlock_applies
- (tp, step,
- target_record_will_replay (inferior_ptid, execution_direction)))
+ (step,
+ target_record_will_replay (inferior_ptid, execution_direction),
+ tp))
{
/* User-settable 'scheduler' mode requires solo thread
resume. */
@@ -3345,13 +3365,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.non_step && !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. */
@@ -3367,7 +3394,7 @@ schedlock_applies (thread_info *tp)
record_will_replay
= target_record_will_replay (tp->ptid, execution_direction);
}
- return schedlock_applies (tp, step, record_will_replay);
+ return schedlock_applies (step, record_will_replay, tp);
}
/* Returns true if scheduler locking applies. STEP indicates whether
@@ -3375,11 +3402,11 @@ schedlock_applies (thread_info *tp)
indicates whether we're about to replay. */
static bool
-schedlock_applies (thread_info *tp, bool step, bool record_will_replay)
+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
@@ -10961,13 +10988,12 @@ Show scheduler locking settings in various conditions."),
&schedlock_show_cmdlist,
&setlist, &showlist);
- add_setshow_boolean_cmd ("non-step", class_run, &schedlock.normal.non_step.value, _("\
-Scheduler locking for non-stepping commands during normal execution."), _("\
-Show scheduler locking for non-stepping commands during normal execution."),
- _("\
-Controls scheduler locking for non-stepping commands during normal execution.\n\
-Commands include continue, until, finish. The setting does not affect \
-stepping."),
+ 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\n\
+stepping and function calls."),
set_schedlock_callback,
show_schedlock_option,
&schedlock_set_cmdlist,
@@ -10985,6 +11011,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
@@ -11005,12 +11041,12 @@ W/o arguments completely locks the scheduler in replay mode."),
&schedlock_set_replay_cmdlist,
0, &schedlock_set_cmdlist);
- add_setshow_boolean_cmd ("non-step", class_run, &schedlock.replay.non_step.value, _("\
-Set scheduler locking for non-stepping commands in replay mode."), _("\
-Show scheduler locking for non-stepping commands in replay mode."), _("\
-Controls scheduler locking for non-stepping commands in replay mode.\n\
-Commands include continue, until, finish. The setting does not affect \
-stepping."),
+ 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\n\
+stepping and function calls."),
set_schedlock_callback,
show_schedlock_option,
&schedlock_set_replay_cmdlist,
@@ -11026,6 +11062,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 {"non-step" "replay non-step" "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 "non-step" "on" "replay non-step" "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 "non-step" "off" "replay non-step" "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,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 "non-step" "on" "replay non-step" "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} {
@@ -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 {non_step step} {
+proc test_schedlock_opts {cont eval step} {
set test "show scheduler-locking"
if {[get_scheduler_locking $test \
- [dict create "non-step" $non_step "replay non-step" "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
@@ -350,7 +351,7 @@ proc test_schedlock_opts {non_step step} {
# Continuing tests.
set locked 0
- if {$non_step eq "on"} {
+ if {$cont eq "on"} {
set locked 1
}
with_test_prefix "cmd=continue" {
@@ -360,17 +361,39 @@ proc test_schedlock_opts {non_step 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 non_step {"off" "on"} {
- foreach step {"off" "on"} {
- with_test_prefix "non-step=$non_step step=$step" {
- gdb_test_no_output "set scheduler-locking non-step $non_step"
- gdb_test_no_output "set scheduler-locking step $step"
- test_schedlock_opts $non_step $step
+foreach cont {"off" "on"} {
+ 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
+ }
}
}
}
@@ -9865,7 +9865,8 @@ proc get_scheduler_locking {{test ""} {expected ""}} {
set test "reading current scheduler-locking mode"
}
- set opts {"non-step" "replay non-step" "replay step" "step"}
+ set opts {"continue" "eval" "replay continue" "replay eval" \
+ "replay step" "step"}
# Fill the missing entries in EXPECTED list.
foreach opt $opts {