Receiving SIGQUIT for forced thread termination may leave sync objects (like virtual_mutex) locked.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49532 Signed-off-by: Paul Gofman pgofman@codeweavers.com --- While the issue I observed in the referenced bug (happening during the process termination only) can be solved in different ways, I suppose protecting the locks from SIGQUIT is preferred because the thread can also be aborted the same way with NtTerminateThread apart from the whole process tear down.
dlls/ntdll/unix/server.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index cadbbe70a25..ac250c5d9d8 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1432,6 +1432,7 @@ void server_init_process(void) sigaddset( &server_block_set, SIGUSR1 ); sigaddset( &server_block_set, SIGUSR2 ); sigaddset( &server_block_set, SIGCHLD ); + sigaddset( &server_block_set, SIGQUIT ); pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
/* receive the first thread request fd on the main socket */
Paul Gofman pgofman@codeweavers.com writes:
Receiving SIGQUIT for forced thread termination may leave sync objects (like virtual_mutex) locked.
I suspect that this will only create a different class of deadlocks, with threads that can't be killed. Avoiding locks at process exit is probably safer.
On 9/14/20 16:01, Alexandre Julliard wrote:
Paul Gofman pgofman@codeweavers.com writes:
Receiving SIGQUIT for forced thread termination may leave sync objects (like virtual_mutex) locked.
I suspect that this will only create a different class of deadlocks, with threads that can't be killed. Avoiding locks at process exit is probably safer.
The same problem may potentially happen if some thread is killed by NtTerminateThread without relation to process exit. SIGQUIT is probably not the only scenario, I guess we can potentially leave the lock when processing, e. g., SEGFAULT during the lock and returning to the syscall frame. Should not we try harder to avoid leaving ntdll.so object locked? Maybe we can instead store the mutex pointer in thread data and unlock it when leaving the ntdll.so scope due to SIGQUIT or SEGFAULT?
Paul Gofman pgofman@codeweavers.com writes:
On 9/14/20 16:01, Alexandre Julliard wrote:
Paul Gofman pgofman@codeweavers.com writes:
Receiving SIGQUIT for forced thread termination may leave sync objects (like virtual_mutex) locked.
I suspect that this will only create a different class of deadlocks, with threads that can't be killed. Avoiding locks at process exit is probably safer.
The same problem may potentially happen if some thread is killed by NtTerminateThread without relation to process exit. SIGQUIT is probably not the only scenario, I guess we can potentially leave the lock when processing, e. g., SEGFAULT during the lock and returning to the syscall frame. Should not we try harder to avoid leaving ntdll.so object locked? Maybe we can instead store the mutex pointer in thread data and unlock it when leaving the ntdll.so scope due to SIGQUIT or SEGFAULT?
In general you can't unwind a mutex lock from an asynchronous signal. In theory of course we should never hang inside the kernel, but NtTerminateThread can just as well hang on a user space lock that can't be recovered from either, so it's not clear that it's a big issue in practice, outside of the process exit case. I'd suggest to fix that one first and see how far it gets us.