else
target_pass_signals (signal_pass);
- /* Request that the target report thread-{created,cloned} events in
- the following situations:
+ /* Request that the target report thread-{created,cloned,exited}
+ events in the following situations:
- If we are performing an in-line step-over-breakpoint, then we
will remove a breakpoint from the target and only run the
current thread. We don't want any new thread (spawned by the
- step) to start running, as it might miss the breakpoint.
+ step) to start running, as it might miss the breakpoint. We
+ need to clear the step-over state if the stepped thread exits,
+ so we also enable thread-exit events.
- If we are stepping over a breakpoint out of line (displaced
stepping) then we won't remove a breakpoint from the target,
but, if the step spawns a new clone thread, then we will need
to fixup the $pc address in the clone child too, so we need it
- to start stopped.
+ to start stopped. We need to release the displaced stepping
+ buffer if the stepped thread exits, so we also enable
+ thread-exit events.
*/
if (step_over_info_valid_p ()
|| displaced_step_in_progress_thread (tp))
{
- gdb_thread_options options = GDB_THREAD_OPTION_CLONE;
+ gdb_thread_options options
+ = GDB_THREAD_OPTION_CLONE | GDB_THREAD_OPTION_EXIT;
if (target_supports_set_thread_options (options))
tp->set_thread_options (options);
else
if (has_single_non_exited_thread (tp->inf))
continue;
+ /* Do not remove the thread if we've requested to be
+ notified of its exit. For example, the thread may be
+ displaced stepping, infrun will need to handle the
+ exit event, and displaced stepping info is recorded
+ in the thread object. If we deleted the thread now,
+ we'd lose that info. */
+ if ((tp->thread_options () & GDB_THREAD_OPTION_EXIT) != 0)
+ continue;
+
/* Not found. */
delete_thread (tp);
}
/* Tell the target to report TARGET_WAITKIND_THREAD_CLONED events
for the thread. */
GDB_THREAD_OPTION_CLONE = 1 << 0,
+
+ /* Tell the target to report TARGET_WAITKIND_THREAD_EXIT events for
+ the thread. */
+ GDB_THREAD_OPTION_EXIT = 1 << 1,
};
DEF_ENUM_FLAGS_TYPE (enum gdb_thread_option, gdb_thread_options);