mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-13 04:46:15 +01:00
main: Don't treat si_pid from pidfd as child exiting
We might repeatedly get si_pid == 0 for a child that hasn't exited, meaning we won't get a correct exit status. This seems to happen when the glib application tracks a ptrace():ed child process; the correct exit status of the process using e.g. a BPF program, where one can observe that glib appears to get it wrong. Fixes: #3071
This commit is contained in:
parent
3513be4e35
commit
8d78fa7887
32
glib/gmain.c
32
glib/gmain.c
@ -5907,24 +5907,34 @@ g_child_watch_dispatch (GSource *source,
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Get the exit status */
|
/* Get the exit status */
|
||||||
if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0 &&
|
if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0)
|
||||||
child_info.si_pid != 0)
|
|
||||||
{
|
{
|
||||||
/* waitid() helpfully provides the wait status in a decomposed
|
if (child_info.si_pid != 0)
|
||||||
* form which is quite useful. Unfortunately we have to report it
|
{
|
||||||
* to the #GChildWatchFunc as a waitpid()-style platform-specific
|
/* waitid() helpfully provides the wait status in a decomposed
|
||||||
* wait status, so that the user code in #GChildWatchFunc can then
|
* form which is quite useful. Unfortunately we have to report it
|
||||||
* call WIFEXITED() (etc.) on it. That means re-composing the
|
* to the #GChildWatchFunc as a waitpid()-style platform-specific
|
||||||
* status information. */
|
* wait status, so that the user code in #GChildWatchFunc can then
|
||||||
wait_status = siginfo_t_to_wait_status (&child_info);
|
* call WIFEXITED() (etc.) on it. That means re-composing the
|
||||||
|
* status information. */
|
||||||
|
wait_status = siginfo_t_to_wait_status (&child_info);
|
||||||
|
child_exited = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_debug (G_STRLOC ": pidfd signaled but pid %d didn't exit",
|
||||||
|
child_watch_source->pid);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Unknown error. We got signaled that the process might be exited,
|
/* Unknown error. We got signaled that the process might be exited,
|
||||||
* but now we failed to reap it? Assume the process is gone and proceed. */
|
* but now we failed to reap it? Assume the process is gone and proceed. */
|
||||||
g_warning (G_STRLOC ": pidfd signaled ready but failed");
|
g_warning (G_STRLOC ": pidfd signaled ready but failed for pid %d",
|
||||||
|
child_watch_source->pid);
|
||||||
|
child_exited = TRUE;
|
||||||
}
|
}
|
||||||
child_exited = TRUE;
|
|
||||||
}
|
}
|
||||||
#endif /* HAVE_PIDFD*/
|
#endif /* HAVE_PIDFD*/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user