Implement GDB_THREAD_OPTION_EXIT support for native Linux
This implements support for the new GDB_THREAD_OPTION_EXIT thread option for native Linux. Reviewed-By: Andrew Burgess <aburgess@redhat.com> Change-Id: Ia69fc0b9b96f9af7de7cefc1ddb1fba9bbb0bb90 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27338
This commit is contained in:
parent
4898949800
commit
a51e14efe2
1 changed files with 31 additions and 13 deletions
|
@ -268,6 +268,18 @@ pending_status_str (lwp_info *lp)
|
|||
return status_to_str (lp->status);
|
||||
}
|
||||
|
||||
/* Return true if we should report exit events for LP. */
|
||||
|
||||
static bool
|
||||
report_exit_events_for (lwp_info *lp)
|
||||
{
|
||||
thread_info *thr = linux_target->find_thread (lp->ptid);
|
||||
gdb_assert (thr != nullptr);
|
||||
|
||||
return (report_thread_events
|
||||
|| (thr->thread_options () & GDB_THREAD_OPTION_EXIT) != 0);
|
||||
}
|
||||
|
||||
|
||||
/* LWP accessors. */
|
||||
|
||||
|
@ -2148,8 +2160,7 @@ wait_lwp (struct lwp_info *lp)
|
|||
/* Check if the thread has exited. */
|
||||
if (WIFEXITED (status) || WIFSIGNALED (status))
|
||||
{
|
||||
if (report_thread_events
|
||||
|| lp->ptid.pid () == lp->ptid.lwp ())
|
||||
if (report_exit_events_for (lp) || is_leader (lp))
|
||||
{
|
||||
linux_nat_debug_printf ("LWP %d exited.", lp->ptid.pid ());
|
||||
|
||||
|
@ -2932,7 +2943,7 @@ linux_nat_filter_event (int lwpid, int status)
|
|||
/* Check if the thread has exited. */
|
||||
if (WIFEXITED (status) || WIFSIGNALED (status))
|
||||
{
|
||||
if (!report_thread_events && !is_leader (lp))
|
||||
if (!report_exit_events_for (lp) && !is_leader (lp))
|
||||
{
|
||||
linux_nat_debug_printf ("%s exited.",
|
||||
lp->ptid.to_string ().c_str ());
|
||||
|
@ -3142,10 +3153,11 @@ check_zombie_leaders (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Convenience function that is called when the kernel reports an exit
|
||||
event. This decides whether to report the event to GDB as a
|
||||
process exit event, a thread exit event, or to suppress the
|
||||
event. */
|
||||
/* Convenience function that is called when we're about to return an
|
||||
event to the core. If the event is an exit or signalled event,
|
||||
then this decides whether to report it as process-wide event, as a
|
||||
thread exit event, or to suppress it. All other event kinds are
|
||||
passed through unmodified. */
|
||||
|
||||
static ptid_t
|
||||
filter_exit_event (struct lwp_info *event_child,
|
||||
|
@ -3153,9 +3165,17 @@ filter_exit_event (struct lwp_info *event_child,
|
|||
{
|
||||
ptid_t ptid = event_child->ptid;
|
||||
|
||||
/* Note we must filter TARGET_WAITKIND_SIGNALLED as well, otherwise
|
||||
if a non-leader thread exits with a signal, we'd report it to the
|
||||
core which would interpret it as the whole-process exiting.
|
||||
There is no TARGET_WAITKIND_THREAD_SIGNALLED event kind. */
|
||||
if (ourstatus->kind () != TARGET_WAITKIND_EXITED
|
||||
&& ourstatus->kind () != TARGET_WAITKIND_SIGNALLED)
|
||||
return ptid;
|
||||
|
||||
if (!is_leader (event_child))
|
||||
{
|
||||
if (report_thread_events)
|
||||
if (report_exit_events_for (event_child))
|
||||
{
|
||||
ourstatus->set_thread_exited (0);
|
||||
/* Delete lwp, but not thread_info, infrun will need it to
|
||||
|
@ -3388,10 +3408,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||
else
|
||||
lp->core = linux_common_core_of_thread (lp->ptid);
|
||||
|
||||
if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
|
||||
return filter_exit_event (lp, ourstatus);
|
||||
|
||||
return lp->ptid;
|
||||
return filter_exit_event (lp, ourstatus);
|
||||
}
|
||||
|
||||
/* Resume LWPs that are currently stopped without any pending status
|
||||
|
@ -4513,7 +4530,8 @@ linux_nat_target::thread_events (int enable)
|
|||
bool
|
||||
linux_nat_target::supports_set_thread_options (gdb_thread_options options)
|
||||
{
|
||||
constexpr gdb_thread_options supported_options = GDB_THREAD_OPTION_CLONE;
|
||||
constexpr gdb_thread_options supported_options
|
||||
= GDB_THREAD_OPTION_CLONE | GDB_THREAD_OPTION_EXIT;
|
||||
return ((options & supported_options) == options);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue