[Bug 1206926] New: process exit status not set by leader thread, when all threads exit using SYS_exit
https://bugzilla.suse.com/show_bug.cgi?id=1206926 Bug ID: 1206926 Summary: process exit status not set by leader thread, when all threads exit using SYS_exit Classification: openSUSE Product: openSUSE Tumbleweed Version: Current Hardware: Other OS: Other Status: NEW Severity: Normal Priority: P5 - None Component: Kernel Assignee: kernel-bugs@opensuse.org Reporter: tdevries@suse.com QA Contact: qa-bugs@suse.de Found By: --- Blocker: --- [ Corresponding upstream gdb PR: https://sourceware.org/bugzilla/show_bug.cgi?id=29965 ] Consider the following gdb testsuite test-case: ... $ cat src/gdb/testsuite/gdb.threads/process-exit-status-is-leader-exit-status.c /* This testcase is part of GDB, the GNU debugger. Copyright 2022-2023 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <pthread.h> #include <unistd.h> #include <sys/syscall.h> #define NUM_THREADS 32 pthread_barrier_t barrier; static void do_exit (int exitcode) { /* Synchronize all threads up to here so that they all exit at roughly the same time. */ pthread_barrier_wait (&barrier); /* All threads exit with SYS_exit, even the main thread, to avoid exiting with a group-exit syscall, as that syscall changes the exit status of all still-alive threads, thus potentially masking a bug. */ syscall (SYS_exit, exitcode); } static void * start (void *arg) { int thread_return_value = *(int *) arg; do_exit (thread_return_value); } int main(void) { pthread_t threads[NUM_THREADS]; int thread_return_val[NUM_THREADS]; int i; pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1); for (i = 0; i < NUM_THREADS; ++i) { thread_return_val[i] = i + 2; pthread_create (&threads[i], NULL, start, &thread_return_val[i]); } do_exit (1); } ... Compile like this: ... $ gcc -lpthread src/gdb/testsuite/gdb.threads/process-exit-status-is-leader-exit-status.c ... On x86_64 openSUSE Tumbleweed 20230102 with kernel 6.1.1-1-default, we have: ... $ ./a.out; echo $? 32 ... Expected value (which I get on say openSUSE Leap 15.4 with kernel 5.14.21) is 1. Possible kernel commit causing this change in behaviour: ... commit d80f7d7b2c75c5954d335dffbccca62a5002c3e0 Author: Eric W. Biederman <ebiederm@xmission.com> Date: Tue Jun 21 14:38:52 2022 -0500 signal: Guarantee that SIGNAL_GROUP_EXIT is set on process exit Track how many threads have not started exiting and when the last thread starts exiting set SIGNAL_GROUP_EXIT. This guarantees that SIGNAL_GROUP_EXIT will get set when a process exits. In practice this achieves nothing as glibc's implementation of _exit calls sys_group_exit then sys_exit. While glibc's implemenation of pthread_exit calls exit (which cleansup and calls _exit) if it is the last thread and sys_exit if it is the last thread. This means the only way the kernel might observe a process that does not set call exit_group is if the language runtime does not use glibc. With more cleanups I hope to move the decrement of quick_threads earlier. Link: https://lkml.kernel.org/r/87bkukd4tc.fsf_-_@email.froward.int.ebiederm.org Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> ... -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1206926 https://bugzilla.suse.com/show_bug.cgi?id=1206926#c1 --- Comment #1 from Tom de Vries <tdevries@suse.com> --- (In reply to Tom de Vries from comment #0)
Author: Eric W. Biederman <ebiederm@xmission.com>
Sent a FYI private email with link to this PR. -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1206926 https://bugzilla.suse.com/show_bug.cgi?id=1206926#c2 --- Comment #2 from Tom de Vries <tdevries@suse.com> --- (In reply to Tom de Vries from comment #1)
(In reply to Tom de Vries from comment #0)
Author: Eric W. Biederman <ebiederm@xmission.com>
Sent a FYI private email with link to this PR.
Got a reply. In there, Eric points out that changed behaviour is likely due to a combination of commits: - d80f7d7b2c75 ("signal: Guarantee that SIGNAL_GROUP_EXIT is set on process exit") - 907c311f37ba ("exit: Fix the exit_code for wait_task_zombie") and shows a patch that should restore the old behaviour. His question is why anybody cares (which I suppose means he doesn't see it as a bug). -- You are receiving this mail because: You are on the CC list for the bug.
https://bugzilla.suse.com/show_bug.cgi?id=1206926 Martin Jambor <mjambor@suse.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mjambor@suse.com -- You are receiving this mail because: You are on the CC list for the bug.
participants (1)
-
bugzilla_noreply@suse.com