@@ -18,16 +18,20 @@ disassemble
* New commands
-set scheduler-locking replay run | replay step | run | step (on|off)
-show scheduler-locking (replay run | replay step | run | step)
- Extend the scheduler locking settings with a set of set/show
+set scheduler-locking eval | replay eval | replay run | replay step | run | step (on|off)
+show scheduler-locking (eval | replay eval | replay run | replay step | run | step)
+ Extend the scheduler-locking settings with a set of set/show
commands, which can be used individually to control the scheduler during
various commands.
- 'replay run' -- when on, the scheduler is locked during non-stepping
+ 'eval' -- when on, the scheduler is locked during expression evaluation
+ in normal mode.
+ 'replay eval' -- when on, the scheduler is locked during expression
+ evaluation in replay mode.
+ 'replay run' -- 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.
- 'run' -- when on, the scheduler is locked during non-stepping commands
+ 'run' -- when on, the scheduler is locked during continuing commands
in normal mode.
'step' -- when on, the scheduler is locked during stepping commands
in normal mode.
@@ -7119,10 +7119,18 @@ record mode, and replay mode. The scheduler locking can be set separately
for stepping and non-stepping commands.
@table @code
+@item eval
+When @code{on} the scheduler is locked for expression evaluation during
+normal execution and record modes, such that only the current thread may run.
+
+@item replay eval
+When @code{on} the scheduler is locked for expression evaluation during
+replay mode, such that only the current thread may run.
+
@item replay run
-When @code{on} the scheduler is locked for non-stepping commands during
-replay mode. For commands like @samp{continue}, @samp{until}, @samp{finish},
-or expression evaluation only the current thread may run.
+When @code{on} the scheduler is locked for continuing commands during
+replay mode. For commands like @samp{continue}, @samp{until} or @samp{finish}
+only the current thread may run.
@item replay step
When @code{on} the scheduler is locked for stepping commands during replay
@@ -7131,10 +7139,9 @@ resumed while you are stepping, so that the focus of debugging does not change
unexpectedly.
@item run
-When @code{on} the scheduler is locked for non-stepping commands during
+When @code{on} the scheduler is locked for continuing commands during
normal execution and record modes. For commands like @samp{continue},
-@samp{until}, @samp{finish}, or expression evaluation only the current
-thread may run.
+@samp{until}, or @samp{finish} only the current thread may run.
@item step
When @code{on} the scheduler is locked for stepping commands during
@@ -110,12 +110,12 @@ static bool step_over_info_valid_p (void);
static bool schedlock_applies_to_thread (thread_info *tp);
-static bool schedlock_applies (bool step);
+static bool schedlock_applies (bool step, thread_info *tp = nullptr);
struct schedlock_options;
static bool schedlock_applies_to_opts (const schedlock_options &opts,
- bool step);
+ bool step, thread_info *tp = nullptr);
/* Command lists for the scheduler locking. */
static cmd_list_element *schedlock_set_cmdlist;
@@ -2361,8 +2361,8 @@ struct schedlock_options
};
schedlock_options () = delete;
- schedlock_options (option run, option step)
- : run (std::move (run)), step (std::move (step))
+ schedlock_options (option eval, option run, option step)
+ : eval (std::move (eval)), run (std::move (run)), step (std::move (step))
{}
/* Forbid accidential copying. */
@@ -2371,7 +2371,9 @@ struct schedlock_options
schedlock_options (schedlock_options &&) = default;
schedlock_options &operator= (schedlock_options &&) = default;
- /* If true, the scheduler is locked during non-stepping. */
+ /* If true, the scheduler is locked during inferior calls. */
+ option eval;
+ /* If true, the scheduler is locked during continuing. */
option run;
/* If true, the scheduler is locked during stepping. */
option step;
@@ -2406,8 +2408,18 @@ static const char schedlock_on[] = "on";
static const char schedlock_step[] = "step";
static const char schedlock_replay[] = "replay";
-schedlock schedlock {{{"run", false}, {"step", false}},
- {{"replay run", true}, {"replay step", true}}};
+schedlock schedlock {
+ {
+ {"eval", false},
+ {"run", false},
+ {"step", false}
+ },
+ {
+ {"replay eval", true},
+ {"replay run", true},
+ {"replay step", true}
+ }
+};
/* A helper function to set scheduler locking shortcuts:
set scheduler-locking on: all options are on.
@@ -2427,9 +2439,11 @@ set_schedlock_shortcut_option (const char *shortcut)
bool any_changed = schedlock.normal.run.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.run.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. */
@@ -2502,7 +2516,9 @@ show_schedlock_option (ui_file *file, int from_tty,
if (strcmp (c->name, "step") == 0)
type = "stepping commands";
else if (strcmp (c->name, "run") == 0)
- type = "non-stepping commands";
+ type = "continuing commands";
+ else if (strcmp (c->name, "eval") == 0)
+ type = "expression evaluation";
else
gdb_assert_not_reached ("Unexpected command name.");
@@ -2538,6 +2554,9 @@ ptid_t
user_visible_resume_ptid (int step)
{
ptid_t resume_ptid;
+ thread_info *tp = nullptr;
+ if (inferior_ptid != null_ptid)
+ tp = inferior_thread ();
if (non_stop)
{
@@ -2545,7 +2564,7 @@ user_visible_resume_ptid (int step)
individually. */
resume_ptid = inferior_ptid;
}
- else if (schedlock_applies (step))
+ else if (schedlock_applies (step, tp))
{
/* User-settable 'scheduler' mode requires solo thread
resume. */
@@ -3334,13 +3353,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.run && !step) || (opts.step && step));
+ bool in_infcall = (tp != nullptr) && tp->control.in_infcall;
+
+ return ((opts.run && !step && !in_infcall)
+ || (opts.step && step)
+ || (opts.eval && in_infcall));
}
/* Returns true if scheduler locking applies to TP. */
@@ -3349,19 +3375,19 @@ static bool
schedlock_applies_to_thread (thread_info *tp)
{
bool step = (tp != nullptr) && tp->control.stepping_command;
- return schedlock_applies (step);
+ return schedlock_applies (step, tp);
}
-/* Returns true if scheduler locking applies. STEP indicates whether
- we're about to do a step/next-like command. */
+/* Returns true if scheduler locking applies to thread TP.
+ STEP indicates whether we're about to do a step/next-like command. */
static bool
-schedlock_applies (bool step)
+schedlock_applies (bool step, thread_info *tp)
{
bool is_replay = target_record_will_replay (minus_one_ptid,
execution_direction);
schedlock_options &opts = is_replay ? schedlock.replay : schedlock.normal;
- return schedlock_applies_to_opts (opts, step);
+ return schedlock_applies_to_opts (opts, step, tp);
}
/* Set process_stratum_target::COMMIT_RESUMED_STATE in all target
@@ -10710,12 +10736,11 @@ Show scheduler locking settings in various conditions."),
&setlist, &showlist);
add_setshow_boolean_cmd ("run", class_run, &schedlock.normal.run.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."),
+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 expression evaluation."),
set_schedlock_callback,
show_schedlock_option,
&schedlock_set_cmdlist,
@@ -10733,6 +10758,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 expression evaluation during normal execution."), _("\
+Show scheduler locking for expression evaluation during normal execution."),
+ _("\
+Controls scheduler locking for expression evaluation 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
@@ -10754,11 +10789,11 @@ W/o arguments completely locks the scheduler in replay mode."),
0, &schedlock_set_cmdlist);
add_setshow_boolean_cmd ("run", class_run, &schedlock.replay.run.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."),
+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 expression evaluation."),
set_schedlock_callback,
show_schedlock_option,
&schedlock_set_replay_cmdlist,
@@ -10774,6 +10809,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 expression evaluation in replay mode."), _("\
+Show scheduler locking for expression evaluation in replay mode."), _("\
+Controls scheduler locking for expression evaluation 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, _("\
@@ -337,10 +337,12 @@ proc test_continue_to_start { mode inf } {
}
# Restore scheduler-locking to its original value.
- gdb_test_no_output "set scheduler-locking replay run [lindex $previous_schedlock_val 0]"
- gdb_test_no_output "set scheduler-locking replay step [lindex $previous_schedlock_val 1]"
- gdb_test_no_output "set scheduler-locking run [lindex $previous_schedlock_val 2]"
- gdb_test_no_output "set scheduler-locking step [lindex $previous_schedlock_val 3]"
+ gdb_test_no_output "set scheduler-locking eval [lindex $previous_schedlock_val 0]"
+ gdb_test_no_output "set scheduler-locking replay eval [lindex $previous_schedlock_val 1]"
+ gdb_test_no_output "set scheduler-locking replay run [lindex $previous_schedlock_val 2]"
+ gdb_test_no_output "set scheduler-locking replay step [lindex $previous_schedlock_val 3]"
+ gdb_test_no_output "set scheduler-locking run [lindex $previous_schedlock_val 4]"
+ gdb_test_no_output "set scheduler-locking step [lindex $previous_schedlock_val 5]"
} 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
@@ -69,7 +69,7 @@ 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 {"on" "on" "on" "on"}] ne "unknown"} \
+gdb_assert {[get_scheduler_locking $test {"on" "on" "on" "on" "on" "on"}] ne "unknown"} \
$test
# Now hand-call a function in each thread, having the function
@@ -142,7 +142,7 @@ 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"
set test "show scheduler-locking off"
-gdb_assert {[get_scheduler_locking $test {"off" "off" "off" "off"}] ne "unknown"} \
+gdb_assert {[get_scheduler_locking $test {"off" "off" "off" "off" "off" "off"}] ne "unknown"} \
$test
# Continue one last time, the program should exit normally.
@@ -50,7 +50,7 @@ gdb_breakpoint [gdb_get_line_number "testmarker01"]
gdb_continue_to_breakpoint "testmarker01"
gdb_test_no_output "set scheduler-locking on"
set test "show scheduler-locking"
-gdb_assert {[get_scheduler_locking $test {"on" "on" "on" "on"}] ne "unknown"} \
+gdb_assert {[get_scheduler_locking $test {"on" "on" "on" "on" "on" "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 {
@@ -320,9 +320,9 @@ foreach schedlock {"off" "step" "on"} {
}
}
-proc test_schedlock_opts {run step} {
+proc test_schedlock_opts {eval run step} {
set test "show scheduler-locking"
- if {[get_scheduler_locking $test [list "off" "off" $run $step]] eq "unknown"} {
+ if {[get_scheduler_locking $test [list $eval "off" "off" "off" $run $step]] eq "unknown"} {
fail $test
} else {
pass $test
@@ -357,6 +357,25 @@ proc test_schedlock_opts {run 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"
@@ -364,10 +383,13 @@ gdb_test_no_output "set scheduler-locking off"
# Test different options of scheduler locking.
foreach run {"off" "on"} {
foreach step {"off" "on"} {
- with_test_prefix "run=$run step=$step" {
- gdb_test_no_output "set scheduler-locking run $run"
- gdb_test_no_output "set scheduler-locking step $step"
- test_schedlock_opts $run $step
+ foreach eval {"off" "on"} {
+ with_test_prefix "run=$run step=$step eval=$eval" {
+ gdb_test_no_output "set scheduler-locking eval $eval"
+ gdb_test_no_output "set scheduler-locking run $run"
+ gdb_test_no_output "set scheduler-locking step $step"
+ test_schedlock_opts $eval $run $step
+ }
}
}
}
@@ -8574,17 +8574,19 @@ proc get_scheduler_locking {{test ""} {expected ""}} {
set any "\[^\r\n\]+"
set on_off "\(?:on|off\)"
- set i [expr 4 - [llength $expected]]
+ set i [expr 6 - [llength $expected]]
while {$i > 0} {
incr i -1
lappend expected $on_off
}
set schedlock_regex \
[multi_line \
- "${any}replay run: +\"\([lindex $expected 0]\)\"${any}non-stepping${any}replay${any}" \
- "${any}replay step: +\"\([lindex $expected 1]\)\"${any}stepping${any}replay${any}" \
- "${any}run: +\"\([lindex $expected 2]\)\"${any}non-stepping${any}normal execution${any}" \
- "${any}step: +\"\([lindex $expected 3]\)\"${any}stepping${any}normal execution${any}"]
+ "${any}eval: +\"\([lindex $expected 0]\)\"${any}expression evaluation${any}normal execution${any}" \
+ "${any}replay eval: +\"\([lindex $expected 1]\)\"${any}expression evaluation${any}replay${any}" \
+ "${any}replay run: +\"\([lindex $expected 2]\)\"${any}continuing${any}replay${any}" \
+ "${any}replay step: +\"\([lindex $expected 3]\)\"${any}stepping${any}replay${any}" \
+ "${any}run: +\"\([lindex $expected 4]\)\"${any}continuing${any}normal execution${any}" \
+ "${any}step: +\"\([lindex $expected 5]\)\"${any}stepping${any}normal execution${any}"]
set current_schedule_locking_mode "unknown"
gdb_test_multiple "show scheduler-locking" $test {
@@ -8593,7 +8595,9 @@ proc get_scheduler_locking {{test ""} {expected ""}} {
[list $expect_out(1,string) \
$expect_out(2,string) \
$expect_out(3,string) \
- $expect_out(4,string)]
+ $expect_out(4,string) \
+ $expect_out(5,string) \
+ $expect_out(6,string)]
}
-re -wrap "" {}
timeout {}
@@ -8623,15 +8627,15 @@ gdb_caching_proc target_supports_scheduler_locking {} {
set test "reading current scheduler-locking mode"
set current_schedule_locking_mode [get_scheduler_locking $test]
- if { $current_scheduler_locking eq "unknown" } {
+ if { $current_schedule_locking_mode eq "unknown" } {
set supports_schedule_locking 0
}
if { $supports_schedule_locking == -1 } {
set test "checking for scheduler-locking support"
- # Try to set scheduler-locking run.
- gdb_test_multiple "set scheduler-locking run [lindex $current_schedule_locking_mode 0]" $test {
+ # Try to set scheduler-locking eval.
+ gdb_test_multiple "set scheduler-locking eval [lindex $current_schedule_locking_mode 0]" $test {
-re "Target '\[^'\]+' cannot support this command\..*$gdb_prompt $" {
set supports_schedule_locking 0
}