mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-18 05:12:33 +08:00
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.
This commit is contained in:
52
gdb/thread.c
52
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user