aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo5
-rw-r--r--gdb/gdbthread.h5
-rw-r--r--gdb/infcmd.c3
-rw-r--r--gdb/infrun.c42
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.threads/schedlock.exp11
8 files changed, 60 insertions, 34 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d131d9a..3695bb3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,22 @@
2015-03-24 Pedro Alves <palves@redhat.com>
+ * gdbthread.h (struct thread_control_state) <stepping_command>:
+ New field.
+ * infcmd.c (step_once): Pass step=1 to clear_proceed_status. Set
+ the thread's stepping_command field.
+ * infrun.c (resume): Check the thread's stepping_command flag to
+ determine which threads should be resumed. Rename 'entry_step'
+ local to user_step.
+ (clear_proceed_status_thread): Clear 'stepping_command'.
+ (schedlock_applies): Change parameter type to struct thread_info
+ pointer. Adjust.
+ (find_thread_needs_step_over): Remove 'step' parameter. Adjust.
+ (switch_back_to_stepped_thread): Adjust calls to
+ 'schedlock_applies'.
+ (_initialize_infrun): Adjust "set scheduler-locking step" help.
+
+2015-03-24 Pedro Alves <palves@redhat.com>
+
* infrun.c (step_start_function): Delete and ...
* gdbthread.h (struct thread_control_state) <step_start_function>:
... now a field here.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index b41c5cb..30d5a5b 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2015-03-24 Pedro Alves <palves@redhat.com>
+
+ * gdb.texinfo (test_step) <set scheduler-locking step>: No longer
+ mention that threads may sometimes run unlocked.
+
2015-03-23 Yurij Grechishhev <yurij.grechishhev@gmail.com>
* gdb.texinfo (Remote configuration): Document "set/show
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7117e42..c03ecb0 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5846,9 +5846,8 @@ 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 only rarely (or never) get a chance to run
-when you step. They are more likely to run when you @samp{next} over a
-function call, and they are completely free to run when you use commands
+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.
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index ce4f76f..bb15717 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -138,6 +138,11 @@ struct thread_control_state
thread was resumed as a result of a command applied to some other
thread (e.g., "next" with scheduler-locking off). */
struct interp *command_interp;
+
+ /* Whether the command that started the thread was a stepping
+ command. This is used to decide whether "set scheduler-locking
+ step" behaves like "on" or "off". */
+ int stepping_command;
};
/* Inferior thread specific part of `struct infcall_suspend_state'.
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 0211b5d..eddbbff 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1047,7 +1047,7 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
THREAD is set. */
struct thread_info *tp = inferior_thread ();
- clear_proceed_status (!skip_subroutines);
+ clear_proceed_status (1);
set_step_frame ();
if (!single_inst)
@@ -1121,6 +1121,7 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
tp->control.step_over_calls = STEP_OVER_ALL;
tp->step_multi = (count > 1);
+ tp->control.stepping_command = 1;
proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
/* For async targets, register a continuation to do any
diff --git a/gdb/infrun.c b/gdb/infrun.c
index be1cc74..a8c3cce 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2038,7 +2038,6 @@ user_visible_resume_ptid (int step)
we get a SIGINT random_signal, but for remote debugging and perhaps
other targets, that's not true).
- STEP nonzero if we should step (zero to continue instead).
SIG is the signal to give the inferior (zero for none). */
void
resume (int step, enum gdb_signal sig)
@@ -2050,13 +2049,10 @@ resume (int step, enum gdb_signal sig)
CORE_ADDR pc = regcache_read_pc (regcache);
struct address_space *aspace = get_regcache_aspace (regcache);
ptid_t resume_ptid;
- /* From here on, this represents the caller's step vs continue
- request, while STEP represents what we'll actually request the
- target to do. STEP can decay from a step to a continue, if e.g.,
- we need to implement single-stepping with breakpoints (software
- single-step). When deciding whether "set scheduler-locking step"
- applies, it's the callers intention that counts. */
- const int entry_step = step;
+ /* This represents the user's step vs continue request. When
+ deciding whether "set scheduler-locking step" applies, it's the
+ user's intention that counts. */
+ const int user_step = tp->control.stepping_command;
tp->stepped_breakpoint = 0;
@@ -2165,7 +2161,7 @@ resume (int step, enum gdb_signal sig)
target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
/* ... and safe to let other threads run, according to
schedlock. */
- resume_ptid = user_visible_resume_ptid (entry_step);
+ resume_ptid = user_visible_resume_ptid (user_step);
target_resume (resume_ptid, 0, GDB_SIGNAL_0);
discard_cleanups (old_cleanups);
return;
@@ -2207,7 +2203,7 @@ resume (int step, enum gdb_signal sig)
Unless we're calling an inferior function, as in that
case we pretend the inferior doesn't run at all. */
if (!tp->control.in_infcall)
- set_running (user_visible_resume_ptid (entry_step), 1);
+ set_running (user_visible_resume_ptid (user_step), 1);
discard_cleanups (old_cleanups);
return;
}
@@ -2280,7 +2276,7 @@ resume (int step, enum gdb_signal sig)
/* Decide the set of threads to ask the target to resume. Start
by assuming everything will be resumed, than narrow the set
by applying increasingly restricting conditions. */
- resume_ptid = user_visible_resume_ptid (entry_step);
+ resume_ptid = user_visible_resume_ptid (user_step);
/* Even if RESUME_PTID is a wildcard, and we end up resuming less
(e.g., we might need to step over a breakpoint), from the
@@ -2413,6 +2409,7 @@ clear_proceed_status_thread (struct thread_info *tp)
tp->control.proceed_to_finish = 0;
tp->control.command_interp = NULL;
+ tp->control.stepping_command = 0;
/* Discard any remaining commands or status from previous stop. */
bpstat_clear (&tp->control.stop_bpstat);
@@ -2492,21 +2489,19 @@ thread_still_needs_step_over (struct thread_info *tp)
we're about to do a step/next-like command to a thread. */
static int
-schedlock_applies (int step)
+schedlock_applies (struct thread_info *tp)
{
return (scheduler_mode == schedlock_on
|| (scheduler_mode == schedlock_step
- && step));
+ && tp->control.stepping_command));
}
/* Look a thread other than EXCEPT that has previously reported a
breakpoint event, and thus needs a step-over in order to make
- progress. Returns NULL is none is found. STEP indicates whether
- we're about to step the current thread, in order to decide whether
- "set scheduler-locking step" applies. */
+ progress. Returns NULL is none is found. */
static struct thread_info *
-find_thread_needs_step_over (int step, struct thread_info *except)
+find_thread_needs_step_over (struct thread_info *except)
{
struct thread_info *tp, *current;
@@ -2517,7 +2512,7 @@ find_thread_needs_step_over (int step, struct thread_info *except)
/* If scheduler locking applies, we can avoid iterating over all
threads. */
- if (schedlock_applies (step))
+ if (schedlock_applies (except))
{
if (except != current
&& thread_still_needs_step_over (current))
@@ -2652,7 +2647,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
Look for a thread other than the current (TP) that reported a
breakpoint hit and hasn't been resumed yet since. */
- step_over = find_thread_needs_step_over (step, tp);
+ step_over = find_thread_needs_step_over (tp);
if (step_over != NULL)
{
if (debug_infrun)
@@ -5592,7 +5587,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
current thread is stepping. If some other thread not the
event thread is stepping, then it must be that scheduler
locking is not in effect. */
- if (schedlock_applies (0))
+ if (schedlock_applies (ecs->event_thread))
return 0;
/* Look for the stepping/nexting thread, and check if any other
@@ -5628,7 +5623,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
stepping, then scheduler locking can't be in effect,
otherwise we wouldn't have resumed the current event
thread in the first place. */
- gdb_assert (!schedlock_applies (currently_stepping (tp)));
+ gdb_assert (!schedlock_applies (tp));
stepping_thread = tp;
}
@@ -7875,9 +7870,8 @@ 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 every single-step operation.\n\
- In this mode, no other thread may run during a step command.\n\
- Other threads may run while stepping over a function call ('next')."),
+step == scheduler locked during stepping commands (step, next, stepi, nexti).\n\
+ In this mode, other threads may run during other commands."),
set_schedlock_func, /* traps on target vector */
show_scheduler_mode,
&setlist, &showlist);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 1286542..824d6fc 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-24 Pedro Alves <palves@redhat.com>
+
+ * gdb.threads/schedlock.exp (test_step): No longer expect that
+ "set scheduler-locking step" with "next" over a function call runs
+ threads unlocked.
+
2015-03-24 Antoine Tremblay <antoine.tremblay@ericsson.com>
* gdb.mi/mi-pending.exp: Fix output of breakpoint test.
diff --git a/gdb/testsuite/gdb.threads/schedlock.exp b/gdb/testsuite/gdb.threads/schedlock.exp
index b47af77..54e847e 100644
--- a/gdb/testsuite/gdb.threads/schedlock.exp
+++ b/gdb/testsuite/gdb.threads/schedlock.exp
@@ -285,8 +285,7 @@ proc test_step { schedlock cmd call_function } {
step_ten_loops $cmd
- # "next" lets other threads run while stepping over functions.
- if { $schedlock == "on" || ($schedlock == "step" && !$call_function) } {
+ if { $schedlock == "on" || $schedlock == "step" } {
set locked 1
} else {
set locked 0
@@ -302,10 +301,10 @@ foreach schedlock {"off" "step" "on"} {
test_step $schedlock "step" 0
}
with_test_prefix "cmd=next" {
- # With "next", and schedlock "step", threads run unlocked
- # when stepping over a function call. This exercises both
- # with and without a function call. Without a function
- # call "next" should behave just like "step".
+ # In GDB <= 7.9, with schedlock "step", "next" would
+ # unlock threads when stepping over a function call. This
+ # exercises "next" with and without a function call. WRT
+ # "schedlock step", "next" should behave just like "step".
foreach call_function {0 1} {
with_test_prefix "call_function=$call_function" {
test_step $schedlock "next" $call_function