diff options
author | Pedro Alves <palves@redhat.com> | 2015-08-07 17:23:58 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-08-07 17:23:58 +0100 |
commit | 4d9d9d0423ed611fa6d620ca3aa088fc16a0d59e (patch) | |
tree | 12db443f6ea89572c1107dd0a04750dc6ea1aa73 /gdb/thread.c | |
parent | c2829269f5af8a860b54ceac3596610b1f51fee5 (diff) | |
download | gdb-4d9d9d0423ed611fa6d620ca3aa088fc16a0d59e.zip gdb-4d9d9d0423ed611fa6d620ca3aa088fc16a0d59e.tar.gz gdb-4d9d9d0423ed611fa6d620ca3aa088fc16a0d59e.tar.bz2 |
Use keep_going in proceed and start_step_over too
The main motivation of this patch is sharing more code between the
proceed (starting the inferior for the first time) and keep_going
(restarting the inferior after handling an event) paths and using the
step_over_chain queue now embedded in the thread_info object for
pending in-line step-overs too (instead of just for displaced
stepping).
So this commit:
- splits out a new keep_going_pass_signal function out of keep_going
that is just like keep_going except for the bits that clear the
signal to pass if the signal is set to "handle nopass".
- makes proceed use keep_going too.
- Makes start_step_over use keep_going_pass_signal instead of lower
level displaced stepping things.
One user visible change: if inserting breakpoints while trying to
proceed fails, we now get:
(gdb) si
Warning:
Could not insert hardware watchpoint 7.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
Command aborted.
(gdb)
while before we only saw warnings with no indication that the command
was cancelled:
(gdb) si
Warning:
Could not insert hardware watchpoint 7.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
(gdb)
Tested on x86_64-linux-gnu, ppc64-linux-gnu and s390-linux-gnu.
gdb/ChangeLog:
2015-08-07 Pedro Alves <palves@redhat.com>
* gdbthread.h (struct thread_info) <prev_pc>: Extend comment.
* infrun.c (struct execution_control_state): Move higher up in the
file.
(reset_ecs): New function.
(start_step_over): Now returns int. Rewrite to use
keep_going_pass_signal instead of manually starting a displaced step.
(resume): Don't call set_running here. If displaced stepping
can't start now, clear trap_expected.
(find_thread_needs_step_over): Delete function.
(proceed): Set up finish_thread_state_cleanup. Call set_running.
If the current thread needs a step over, push it in the step-over
chain. Don't set insert breakpoints nor call resume directly
here. Instead rewrite to use start_step_over and
keep_going_pass_signal.
(finish_step_over): New function.
(handle_signal_stop): Call finish_step_over instead of
start_step_over.
(switch_back_to_stepped_thread): If the event thread needs another
step-over do that first. Use start_step_over.
(keep_going_pass_signal): New function, factored out from ...
(keep_going): ... here.
(_initialize_infrun): Comment moved here.
* thread.c (set_running_thread): New function.
(set_running, finish_thread_state): Use set_running_thread.
Diffstat (limited to 'gdb/thread.c')
-rw-r--r-- | gdb/thread.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/gdb/thread.c b/gdb/thread.c index 28e5ef8..3e3f419 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -852,44 +852,62 @@ thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid) observer_notify_thread_ptid_changed (old_ptid, new_ptid); } +/* Helper for set_running, that marks one thread either running or + stopped. */ + +static int +set_running_thread (struct thread_info *tp, int running) +{ + int started = 0; + + if (running && tp->state == THREAD_STOPPED) + started = 1; + tp->state = running ? THREAD_RUNNING : THREAD_STOPPED; + + if (!running) + { + /* If the thread is now marked stopped, remove it from + the step-over queue, so that we don't try to resume + it until the user wants it to. */ + if (tp->step_over_next != NULL) + thread_step_over_chain_remove (tp); + } + + return started; +} + void set_running (ptid_t ptid, int running) { struct thread_info *tp; int all = ptid_equal (ptid, minus_one_ptid); + int any_started = 0; /* We try not to notify the observer if no thread has actually changed the running state -- merely to reduce the number of messages to frontend. Frontend is supposed to handle multiple *running just fine. */ if (all || ptid_is_pid (ptid)) { - int any_started = 0; - for (tp = thread_list; tp; tp = tp->next) if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid)) { if (tp->state == THREAD_EXITED) continue; - if (running && tp->state == THREAD_STOPPED) + + if (set_running_thread (tp, running)) any_started = 1; - tp->state = running ? THREAD_RUNNING : THREAD_STOPPED; } - if (any_started) - observer_notify_target_resumed (ptid); } else { - int started = 0; - tp = find_thread_ptid (ptid); - gdb_assert (tp); + gdb_assert (tp != NULL); gdb_assert (tp->state != THREAD_EXITED); - if (running && tp->state == THREAD_STOPPED) - started = 1; - tp->state = running ? THREAD_RUNNING : THREAD_STOPPED; - if (started) - observer_notify_target_resumed (ptid); + if (set_running_thread (tp, running)) + any_started = 1; } + if (any_started) + observer_notify_target_resumed (ptid); } static int @@ -1008,9 +1026,8 @@ finish_thread_state (ptid_t ptid) continue; if (all || ptid_get_pid (ptid) == ptid_get_pid (tp->ptid)) { - if (tp->executing && tp->state == THREAD_STOPPED) + if (set_running_thread (tp, tp->executing)) any_started = 1; - tp->state = tp->executing ? THREAD_RUNNING : THREAD_STOPPED; } } } @@ -1020,9 +1037,8 @@ finish_thread_state (ptid_t ptid) gdb_assert (tp); if (tp->state != THREAD_EXITED) { - if (tp->executing && tp->state == THREAD_STOPPED) + if (set_running_thread (tp, tp->executing)) any_started = 1; - tp->state = tp->executing ? THREAD_RUNNING : THREAD_STOPPED; } } |