Add first test for premature thread-group leader exit. Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx> --- tools/testing/selftests/pidfd/pidfd_info_test.c | 38 ++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/pidfd/pidfd_info_test.c b/tools/testing/selftests/pidfd/pidfd_info_test.c index 09bc4ae7aed5..28a28ae4686a 100644 --- a/tools/testing/selftests/pidfd/pidfd_info_test.c +++ b/tools/testing/selftests/pidfd/pidfd_info_test.c @@ -236,7 +236,7 @@ static void *pidfd_info_pause_thread(void *arg) TEST_F(pidfd_info, thread_group) { - pid_t pid_leader, pid_thread; + pid_t pid_leader, pid_poller, pid_thread; pthread_t thread; int nevents, pidfd_leader, pidfd_thread, pidfd_leader_thread, ret; int ipc_sockets[2]; @@ -262,6 +262,35 @@ TEST_F(pidfd_info, thread_group) syscall(__NR_exit, EXIT_SUCCESS); } + /* + * Opening a PIDFD_THREAD aka thread-specific pidfd based on a + * thread-group leader must succeed. + */ + pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD); + ASSERT_GE(pidfd_leader_thread, 0); + + pid_poller = fork(); + ASSERT_GE(pid_poller, 0); + if (pid_poller == 0) { + /* + * We can't poll and wait for the old thread-group + * leader to exit using a thread-specific pidfd. The + * thread-group leader exited prematurely and + * notification is delayed until all subthreads have + * exited. + */ + fds.events = POLLIN; + fds.fd = pidfd_leader_thread; + nevents = poll(&fds, 1, 10000 /* wait 5 seconds */); + if (nevents != 0) + _exit(EXIT_FAILURE); + if (fds.revents & POLLIN) + _exit(EXIT_FAILURE); + if (fds.revents & POLLHUP) + _exit(EXIT_FAILURE); + _exit(EXIT_SUCCESS); + } + /* Retrieve the tid of the thread. */ EXPECT_EQ(close(ipc_sockets[1]), 0); ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread)); @@ -275,12 +304,7 @@ TEST_F(pidfd_info, thread_group) pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD); ASSERT_GE(pidfd_thread, 0); - /* - * Opening a PIDFD_THREAD aka thread-specific pidfd based on a - * thread-group leader must succeed. - */ - pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD); - ASSERT_GE(pidfd_leader_thread, 0); + ASSERT_EQ(wait_for_pid(pid_poller), 0); /* * Note that pidfd_leader is a thread-group pidfd, so polling on it -- 2.47.2