Created attachment 8848 [details] demo of thread acting on cancellation request while terminating Returning from a thread should behave as calling pthread_exit(), and XSH 2.95, under the epigraph "Thread Cancellation Cleanup Handlers" requires pthread_exit() to set the cancellation state and type to disabled and deferred, respectively. The attached program is supposed to endlessly loop creating an asynchronously cancellable thread, and then cancelling and joining it. Instead of that, after a while, the program exits. This does not happen if the created thread calls pthread_exit() instead of returning. Setting the cancellation state and type to disabled and deferred in nptl/pthread_create.c:START_THREAD_DEFN after returning from/long jumping out of start_routine fixes this test case. This fix is similar to one in musl (http://git.musl-libc.org/cgit/musl/commit/?id=36d8e972231c397194e513691d09f7d489de0a62), the test program deadlocks in musl prior to that commit.
The issue is fixed on 2.34 (8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b), although it does fully follow the POSIX XSH 2.9.5 Thread Cancellation under the heading Thread Cancellation Cleanup Handlers that states that when a cancellation request is acted upon, or when a thread calls pthread_exit(), the thread first disables cancellation by setting its cancelability state to PTHREAD_CANCEL_DISABLE and its cancelability type to PTHREAD_CANCEL_DEFERRED. The issue is _pthread_enable_asynccancel' explicit enabled asynchronous cancellation, so an interrupted syscall within the cancellation cleanup handlers might see an invalid cancelling type. To fully fix it we will need to rewrite how cancellation is done (as my proposed solution to BZ#12683). I will send a second part for this bug where a cancellation callback should see the expected cancellation state and type (although changing the cancellation state/type on cancellation callback is undefined).