Replace finish_thread_state_cleanup with a RAII class
gdb/ChangeLog: 2018-04-10 Pedro Alves <palves@redhat.com> * gdbthread.h (finish_thread_state_cleanup): Delete declaration. (scoped_finish_thread_state): New class. * infcmd.c (run_command_1): Use it instead of finish_thread_state cleanup. * infrun.c (proceed, prepare_for_detach, wait_for_inferior) (fetch_inferior_event, normal_stop): Likewise. * thread.c (finish_thread_state_cleanup): Delete.
This commit is contained in:
parent
d4ae193277
commit
731f534f91
5 changed files with 63 additions and 50 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
2018-04-10 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* gdbthread.h (finish_thread_state_cleanup): Delete declaration.
|
||||||
|
(scoped_finish_thread_state): New class.
|
||||||
|
* infcmd.c (run_command_1): Use it instead of finish_thread_state
|
||||||
|
cleanup.
|
||||||
|
* infrun.c (proceed, prepare_for_detach, wait_for_inferior)
|
||||||
|
(fetch_inferior_event, normal_stop): Likewise.
|
||||||
|
* thread.c (finish_thread_state_cleanup): Delete.
|
||||||
|
|
||||||
2018-04-09 Simon Marchi <simon.marchi@polymtl.ca>
|
2018-04-09 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
Pedro Alves <palves@redhat.com>
|
Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
|
|
@ -567,10 +567,33 @@ extern int threads_are_executing (void);
|
||||||
Notifications are only emitted if the thread state did change. */
|
Notifications are only emitted if the thread state did change. */
|
||||||
extern void finish_thread_state (ptid_t ptid);
|
extern void finish_thread_state (ptid_t ptid);
|
||||||
|
|
||||||
/* Same as FINISH_THREAD_STATE, but with an interface suitable to be
|
/* Calls finish_thread_state on scope exit, unless release() is called
|
||||||
registered as a cleanup. PTID_P points to the ptid_t that is
|
to disengage. */
|
||||||
passed to FINISH_THREAD_STATE. */
|
class scoped_finish_thread_state
|
||||||
extern void finish_thread_state_cleanup (void *ptid_p);
|
{
|
||||||
|
public:
|
||||||
|
explicit scoped_finish_thread_state (ptid_t ptid)
|
||||||
|
: m_ptid (ptid)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~scoped_finish_thread_state ()
|
||||||
|
{
|
||||||
|
if (!m_released)
|
||||||
|
finish_thread_state (m_ptid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disengage. */
|
||||||
|
void release ()
|
||||||
|
{
|
||||||
|
m_released = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DISABLE_COPY_AND_ASSIGN (scoped_finish_thread_state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_released = false;
|
||||||
|
ptid_t m_ptid;
|
||||||
|
};
|
||||||
|
|
||||||
/* Commands with a prefix of `thread'. */
|
/* Commands with a prefix of `thread'. */
|
||||||
extern struct cmd_list_element *thread_cmd_list;
|
extern struct cmd_list_element *thread_cmd_list;
|
||||||
|
|
13
gdb/infcmd.c
13
gdb/infcmd.c
|
@ -565,8 +565,6 @@ static void
|
||||||
run_command_1 (const char *args, int from_tty, enum run_how run_how)
|
run_command_1 (const char *args, int from_tty, enum run_how run_how)
|
||||||
{
|
{
|
||||||
const char *exec_file;
|
const char *exec_file;
|
||||||
struct cleanup *old_chain;
|
|
||||||
ptid_t ptid;
|
|
||||||
struct ui_out *uiout = current_uiout;
|
struct ui_out *uiout = current_uiout;
|
||||||
struct target_ops *run_target;
|
struct target_ops *run_target;
|
||||||
int async_exec;
|
int async_exec;
|
||||||
|
@ -655,11 +653,10 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
|
||||||
events --- the frontend shouldn't see them as stopped. In
|
events --- the frontend shouldn't see them as stopped. In
|
||||||
all-stop, always finish the state of all threads, as we may be
|
all-stop, always finish the state of all threads, as we may be
|
||||||
resuming more than just the new process. */
|
resuming more than just the new process. */
|
||||||
if (non_stop)
|
ptid_t finish_ptid = (non_stop
|
||||||
ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
|
? ptid_t (current_inferior ()->pid)
|
||||||
else
|
: minus_one_ptid);
|
||||||
ptid = minus_one_ptid;
|
scoped_finish_thread_state finish_state (finish_ptid);
|
||||||
old_chain = make_cleanup (finish_thread_state_cleanup, &ptid);
|
|
||||||
|
|
||||||
/* Pass zero for FROM_TTY, because at this point the "run" command
|
/* Pass zero for FROM_TTY, because at this point the "run" command
|
||||||
has done its thing; now we are setting up the running program. */
|
has done its thing; now we are setting up the running program. */
|
||||||
|
@ -680,7 +677,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
|
||||||
|
|
||||||
/* Since there was no error, there's no need to finish the thread
|
/* Since there was no error, there's no need to finish the thread
|
||||||
states here. */
|
states here. */
|
||||||
discard_cleanups (old_chain);
|
finish_state.release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
49
gdb/infrun.c
49
gdb/infrun.c
|
@ -2979,7 +2979,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
|
||||||
ptid_t resume_ptid;
|
ptid_t resume_ptid;
|
||||||
struct execution_control_state ecss;
|
struct execution_control_state ecss;
|
||||||
struct execution_control_state *ecs = &ecss;
|
struct execution_control_state *ecs = &ecss;
|
||||||
struct cleanup *old_chain;
|
|
||||||
int started;
|
int started;
|
||||||
|
|
||||||
/* If we're stopped at a fork/vfork, follow the branch set by the
|
/* If we're stopped at a fork/vfork, follow the branch set by the
|
||||||
|
@ -3043,7 +3042,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
|
||||||
/* If an exception is thrown from this point on, make sure to
|
/* If an exception is thrown from this point on, make sure to
|
||||||
propagate GDB's knowledge of the executing state to the
|
propagate GDB's knowledge of the executing state to the
|
||||||
frontend/user running state. */
|
frontend/user running state. */
|
||||||
old_chain = make_cleanup (finish_thread_state_cleanup, &resume_ptid);
|
scoped_finish_thread_state finish_state (resume_ptid);
|
||||||
|
|
||||||
/* Even if RESUME_PTID is a wildcard, and we end up resuming fewer
|
/* Even if RESUME_PTID is a wildcard, and we end up resuming fewer
|
||||||
threads (e.g., we might need to set threads stepping over
|
threads (e.g., we might need to set threads stepping over
|
||||||
|
@ -3198,7 +3197,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
|
||||||
|
|
||||||
target_commit_resume ();
|
target_commit_resume ();
|
||||||
|
|
||||||
discard_cleanups (old_chain);
|
finish_state.release ();
|
||||||
|
|
||||||
/* Tell the event loop to wait for it to stop. If the target
|
/* Tell the event loop to wait for it to stop. If the target
|
||||||
supports asynchronous execution, it'll do this from within
|
supports asynchronous execution, it'll do this from within
|
||||||
|
@ -3641,7 +3640,6 @@ prepare_for_detach (void)
|
||||||
|
|
||||||
while (!ptid_equal (displaced->step_ptid, null_ptid))
|
while (!ptid_equal (displaced->step_ptid, null_ptid))
|
||||||
{
|
{
|
||||||
struct cleanup *old_chain_2;
|
|
||||||
struct execution_control_state ecss;
|
struct execution_control_state ecss;
|
||||||
struct execution_control_state *ecs;
|
struct execution_control_state *ecs;
|
||||||
|
|
||||||
|
@ -3663,14 +3661,13 @@ prepare_for_detach (void)
|
||||||
/* If an error happens while handling the event, propagate GDB's
|
/* If an error happens while handling the event, propagate GDB's
|
||||||
knowledge of the executing state to the frontend/user running
|
knowledge of the executing state to the frontend/user running
|
||||||
state. */
|
state. */
|
||||||
old_chain_2 = make_cleanup (finish_thread_state_cleanup,
|
scoped_finish_thread_state finish_state (minus_one_ptid);
|
||||||
&minus_one_ptid);
|
|
||||||
|
|
||||||
/* Now figure out what to do with the result of the result. */
|
/* Now figure out what to do with the result of the result. */
|
||||||
handle_inferior_event (ecs);
|
handle_inferior_event (ecs);
|
||||||
|
|
||||||
/* No error, don't finish the state yet. */
|
/* No error, don't finish the state yet. */
|
||||||
discard_cleanups (old_chain_2);
|
finish_state.release ();
|
||||||
|
|
||||||
/* Breakpoints and watchpoints are not installed on the target
|
/* Breakpoints and watchpoints are not installed on the target
|
||||||
at this point, and signals are passed directly to the
|
at this point, and signals are passed directly to the
|
||||||
|
@ -3696,7 +3693,6 @@ void
|
||||||
wait_for_inferior (void)
|
wait_for_inferior (void)
|
||||||
{
|
{
|
||||||
struct cleanup *old_cleanups;
|
struct cleanup *old_cleanups;
|
||||||
struct cleanup *thread_state_chain;
|
|
||||||
|
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered
|
fprintf_unfiltered
|
||||||
|
@ -3709,7 +3705,7 @@ wait_for_inferior (void)
|
||||||
/* If an error happens while handling the event, propagate GDB's
|
/* If an error happens while handling the event, propagate GDB's
|
||||||
knowledge of the executing state to the frontend/user running
|
knowledge of the executing state to the frontend/user running
|
||||||
state. */
|
state. */
|
||||||
thread_state_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
|
scoped_finish_thread_state finish_state (minus_one_ptid);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -3740,7 +3736,7 @@ wait_for_inferior (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No error, don't finish the state yet. */
|
/* No error, don't finish the state yet. */
|
||||||
discard_cleanups (thread_state_chain);
|
finish_state.release ();
|
||||||
|
|
||||||
do_cleanups (old_cleanups);
|
do_cleanups (old_cleanups);
|
||||||
}
|
}
|
||||||
|
@ -3859,7 +3855,6 @@ fetch_inferior_event (void *client_data)
|
||||||
struct execution_control_state ecss;
|
struct execution_control_state ecss;
|
||||||
struct execution_control_state *ecs = &ecss;
|
struct execution_control_state *ecs = &ecss;
|
||||||
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
||||||
struct cleanup *ts_old_chain;
|
|
||||||
int cmd_done = 0;
|
int cmd_done = 0;
|
||||||
ptid_t waiton_ptid = minus_one_ptid;
|
ptid_t waiton_ptid = minus_one_ptid;
|
||||||
|
|
||||||
|
@ -3912,14 +3907,12 @@ fetch_inferior_event (void *client_data)
|
||||||
/* If an error happens while handling the event, propagate GDB's
|
/* If an error happens while handling the event, propagate GDB's
|
||||||
knowledge of the executing state to the frontend/user running
|
knowledge of the executing state to the frontend/user running
|
||||||
state. */
|
state. */
|
||||||
if (!target_is_non_stop_p ())
|
ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
|
||||||
ts_old_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
|
scoped_finish_thread_state finish_state (finish_ptid);
|
||||||
else
|
|
||||||
ts_old_chain = make_cleanup (finish_thread_state_cleanup, &ecs->ptid);
|
|
||||||
|
|
||||||
/* Get executed before make_cleanup_restore_current_thread above to apply
|
/* Get executed before make_cleanup_restore_current_thread above to apply
|
||||||
still for the thread which has thrown the exception. */
|
still for the thread which has thrown the exception. */
|
||||||
make_bpstat_clear_actions_cleanup ();
|
struct cleanup *ts_old_chain = make_bpstat_clear_actions_cleanup ();
|
||||||
|
|
||||||
make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup, NULL);
|
make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup, NULL);
|
||||||
|
|
||||||
|
@ -3974,9 +3967,11 @@ fetch_inferior_event (void *client_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No error, don't finish the thread states yet. */
|
|
||||||
discard_cleanups (ts_old_chain);
|
discard_cleanups (ts_old_chain);
|
||||||
|
|
||||||
|
/* No error, don't finish the thread states yet. */
|
||||||
|
finish_state.release ();
|
||||||
|
|
||||||
/* Revert thread and frame. */
|
/* Revert thread and frame. */
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
|
|
||||||
|
@ -8165,8 +8160,6 @@ normal_stop (void)
|
||||||
{
|
{
|
||||||
struct target_waitstatus last;
|
struct target_waitstatus last;
|
||||||
ptid_t last_ptid;
|
ptid_t last_ptid;
|
||||||
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
|
||||||
ptid_t pid_ptid;
|
|
||||||
|
|
||||||
get_last_target_status (&last_ptid, &last);
|
get_last_target_status (&last_ptid, &last);
|
||||||
|
|
||||||
|
@ -8176,8 +8169,11 @@ normal_stop (void)
|
||||||
propagate GDB's knowledge of the executing state to the
|
propagate GDB's knowledge of the executing state to the
|
||||||
frontend/user running state. A QUIT is an easy exception to see
|
frontend/user running state. A QUIT is an easy exception to see
|
||||||
here, so do this before any filtered output. */
|
here, so do this before any filtered output. */
|
||||||
|
|
||||||
|
gdb::optional<scoped_finish_thread_state> maybe_finish_thread_state;
|
||||||
|
|
||||||
if (!non_stop)
|
if (!non_stop)
|
||||||
make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
|
maybe_finish_thread_state.emplace (minus_one_ptid);
|
||||||
else if (last.kind == TARGET_WAITKIND_SIGNALLED
|
else if (last.kind == TARGET_WAITKIND_SIGNALLED
|
||||||
|| last.kind == TARGET_WAITKIND_EXITED)
|
|| last.kind == TARGET_WAITKIND_EXITED)
|
||||||
{
|
{
|
||||||
|
@ -8186,14 +8182,11 @@ normal_stop (void)
|
||||||
"checkpoint", when the current checkpoint/fork exits,
|
"checkpoint", when the current checkpoint/fork exits,
|
||||||
linux-fork.c automatically switches to another fork from
|
linux-fork.c automatically switches to another fork from
|
||||||
within target_mourn_inferior. */
|
within target_mourn_inferior. */
|
||||||
if (!ptid_equal (inferior_ptid, null_ptid))
|
if (inferior_ptid != null_ptid)
|
||||||
{
|
maybe_finish_thread_state.emplace (ptid_t (inferior_ptid.pid ()));
|
||||||
pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
|
|
||||||
make_cleanup (finish_thread_state_cleanup, &pid_ptid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (last.kind != TARGET_WAITKIND_NO_RESUMED)
|
else if (last.kind != TARGET_WAITKIND_NO_RESUMED)
|
||||||
make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
|
maybe_finish_thread_state.emplace (inferior_ptid);
|
||||||
|
|
||||||
/* As we're presenting a stop, and potentially removing breakpoints,
|
/* As we're presenting a stop, and potentially removing breakpoints,
|
||||||
update the thread list so we can tell whether there are threads
|
update the thread list so we can tell whether there are threads
|
||||||
|
@ -8225,7 +8218,7 @@ normal_stop (void)
|
||||||
after this event is handled, so we're not really switching, only
|
after this event is handled, so we're not really switching, only
|
||||||
informing of a stop. */
|
informing of a stop. */
|
||||||
if (!non_stop
|
if (!non_stop
|
||||||
&& !ptid_equal (previous_inferior_ptid, inferior_ptid)
|
&& previous_inferior_ptid != inferior_ptid
|
||||||
&& target_has_execution
|
&& target_has_execution
|
||||||
&& last.kind != TARGET_WAITKIND_SIGNALLED
|
&& last.kind != TARGET_WAITKIND_SIGNALLED
|
||||||
&& last.kind != TARGET_WAITKIND_EXITED
|
&& last.kind != TARGET_WAITKIND_EXITED
|
||||||
|
@ -8266,7 +8259,7 @@ normal_stop (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let the user/frontend see the threads as stopped. */
|
/* Let the user/frontend see the threads as stopped. */
|
||||||
do_cleanups (old_chain);
|
maybe_finish_thread_state.reset ();
|
||||||
|
|
||||||
/* Select innermost stack frame - i.e., current frame is frame 0,
|
/* Select innermost stack frame - i.e., current frame is frame 0,
|
||||||
and current location is based on that. Handle the case where the
|
and current location is based on that. Handle the case where the
|
||||||
|
|
10
gdb/thread.c
10
gdb/thread.c
|
@ -1040,16 +1040,6 @@ finish_thread_state (ptid_t ptid)
|
||||||
gdb::observers::target_resumed.notify (ptid);
|
gdb::observers::target_resumed.notify (ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
finish_thread_state_cleanup (void *arg)
|
|
||||||
{
|
|
||||||
ptid_t *ptid_p = (ptid_t *) arg;
|
|
||||||
|
|
||||||
gdb_assert (arg);
|
|
||||||
|
|
||||||
finish_thread_state (*ptid_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See gdbthread.h. */
|
/* See gdbthread.h. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue