diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a2bd843404..ee90a762b4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2015-09-18 Markus Metzger + + * NEWS: Announce new scheduler-locking mode. + * infrun.c (schedlock_replay): New. + (scheduler_enums): Add schedlock_replay. + (scheduler_mode): Change default to schedlock_replay. + (user_visible_resume_ptid): Handle schedlock_replay. + (clear_proceed_status_thread): Stop replaying if resumed thread is + not replaying. + (schedlock_applies): Handle schedlock_replay. + (_initialize_infrun): Document new scheduler-locking mode. + * record-btrace.c (record_btrace_resume): Remove code to stop other + threads when not replaying the resumed thread. + 2015-09-18 Markus Metzger * record-btrace.c ((record_btrace_will_replay): New. diff --git a/gdb/NEWS b/gdb/NEWS index 0d17ef4ff1..86c6f021a1 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -45,6 +45,9 @@ show remote multiprocess-extensions-packet The "/m" option is now considered deprecated: its "source-centric" output hasn't proved useful in practice. +* The "set scheduler-locking" command supports a new mode "replay". + It behaves like "off" in record mode and like "on" in replay mode. + * Support for various ROM monitors has been removed: target dbug dBUG ROM monitor for Motorola ColdFire diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 1e16e92932..9164b89379 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2015-09-18 Markus Metzger + + * gdb.texinfo (All-Stop Mode): Describe new scheduler-locking mode. + 2015-09-15 Pedro Alves PR remote/18965 diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 4ecdb8fc7b..0687039630 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -5836,17 +5836,20 @@ locking the OS scheduler to allow only a single thread to run. @item set scheduler-locking @var{mode} @cindex scheduler locking mode @cindex lock scheduler -Set the scheduler locking mode. If it is @code{off}, then there is no -locking and any thread may run at any time. If @code{on}, then only the -current thread may run when the inferior is resumed. The @code{step} -mode optimizes for single-stepping; it prevents other threads -from preempting the current thread while you are stepping, so that -the focus of debugging does not change unexpectedly. -Other threads 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}. However, unless another -thread hits a breakpoint during its timeslice, @value{GDBN} does not change -the current thread away from the thread that you are debugging. +Set the scheduler locking mode. It applies to normal execution, +record mode, and replay mode. If it is @code{off}, then there is no +locking and any thread may run at any time. If @code{on}, then only +the current thread may run when the inferior is resumed. The +@code{step} mode optimizes for single-stepping; it prevents other +threads from preempting the current thread while you are stepping, so +that the focus of debugging does not change unexpectedly. Other +threads 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}. However, unless another thread hits a +breakpoint during its timeslice, @value{GDBN} does not change the +current thread away from the thread that you are debugging. The +@code{replay} mode behaves like @code{off} in record mode and like +@code{on} in replay mode. @item show scheduler-locking Display the current scheduler locking mode. diff --git a/gdb/infrun.c b/gdb/infrun.c index 75ac80abd9..701ea37eb5 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2166,13 +2166,15 @@ resume_cleanups (void *ignore) 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, NULL }; -static const char *scheduler_mode = schedlock_off; +static const char *scheduler_mode = schedlock_replay; static void show_scheduler_mode (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -2238,6 +2240,13 @@ user_visible_resume_ptid (int step) resume. */ resume_ptid = inferior_ptid; } + else if ((scheduler_mode == schedlock_replay) + && target_record_will_replay (minus_one_ptid, execution_direction)) + { + /* User-settable 'scheduler' mode requires solo thread resume in replay + mode. */ + resume_ptid = inferior_ptid; + } else if (!sched_multi && target_supports_multi_process ()) { /* Resume all threads of the current process (and none of other @@ -2803,6 +2812,18 @@ clear_proceed_status_thread (struct thread_info *tp) void clear_proceed_status (int step) { + /* With scheduler-locking replay, stop replaying other threads if we're + not replaying the user-visible resume ptid. + + This is a convenience feature to not require the user to explicitly + stop replaying the other threads. We're assuming that the user's + intent is to resume tracing the recorded process. */ + if (!non_stop && scheduler_mode == schedlock_replay + && target_record_is_replaying (minus_one_ptid) + && !target_record_will_replay (user_visible_resume_ptid (step), + execution_direction)) + target_record_stop_replaying (); + if (!non_stop) { struct thread_info *tp; @@ -2890,7 +2911,10 @@ schedlock_applies (struct thread_info *tp) { return (scheduler_mode == schedlock_on || (scheduler_mode == schedlock_step - && tp->control.stepping_command)); + && tp->control.stepping_command) + || (scheduler_mode == schedlock_replay + && target_record_will_replay (minus_one_ptid, + execution_direction))); } /* Basic routine for continuing the program in various fashions. @@ -9187,10 +9211,13 @@ By default, the debugger will use the same inferior."), 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\ -step == scheduler locked during stepping commands (step, next, stepi, nexti).\n\ - In this mode, other threads may run during other commands."), +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, &setlist, &showlist); diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index df15d7770f..42195d1a1e 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -1903,22 +1903,16 @@ record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step, to not change the execution direction in-between. */ record_btrace_resume_exec_dir = execution_direction; - /* For all-stop targets... */ + /* For all-stop targets we pick the current thread when asked to resume an + entire process or everything. */ if (!target_is_non_stop_p ()) { - /* ...we pick the current thread when asked to resume an entire process - or everything. */ if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid)) ptid = inferior_ptid; tp = find_thread_ptid (ptid); if (tp == NULL) error (_("Cannot find thread to resume.")); - - /* ...and we stop replaying other threads if the thread to resume is not - replaying. */ - if (!btrace_is_replaying (tp) && execution_direction != EXEC_REVERSE) - target_record_stop_replaying (); } /* As long as we're not replaying, just forward the request.