Using a dedicated exit jmpbuf and removing the need for assembly routines.
When Wine handles an exception in unix code, we return to user mode by jumping to the last syscall frame. This can leave some pthread cancel cleanups registered, in the pthread internal linked list, and at the same time later overwrite the stack frame they were registered for.
In the same way, jumping to the exit frame on thread exit or abort, can also leave some cleanup handlers registered for invalid stack frames.
Depending on the implementation, calling pthread_exit will cause all the registered pthread cleanup handlers to be called, possibly jumping back to now overwritten stack frames and causing segmentation faults.
Exiting a pthread normally, by returning from its procedure, or calling exit(0) for the main thread doesn't run pthread_exit and doesn't call cleanup handlers, avoiding that situation.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213
### Additional note:
For robustness, we should probably try to execute these cleanup handlers when unwinding the stack frames, as we would otherwise leave pthread objects in a potential problematic state (like a mutex locked, etc).
It is however hard to do so when the handlers are registered from some C code: pthread C implementation is done by calling some internal pthread functions to register the handlers, and they aren't registered as standard unwind handlers.
Only pthread_cancel and pthread_exit can unwind and call / unregister the C handlers, but interrupting that procedure, for instance calling setjmp / longjmp from withing our own handler isn't supported.
From C++ code, pthread cleanup handlers are registered through C++ class constructors / destructors, and it would then be possible to partially unwind and call them at the same time.
-- v12: ntdll: Remove the signal_exit_thread wrapper. ntdll: Get rid of the thread exit frame on ARM. ntdll: Get rid of the thread exit frame on ARM64. ntdll: Get rid of the thread exit frame on x86-64. ntdll: Get rid of the thread exit frame on i386. ntdll: Switch to the kernel stack to abort a thread on ARM. ntdll: Switch to the kernel stack to abort a thread on ARM64. ntdll: Switch to the kernel stack to abort a thread on x86-64. ntdll: Switch to the kernel stack to abort a thread on i386. ntdll: Connect syscall frames across user callbacks on ARM. ntdll: Connect syscall frames across user callbacks on ARM64. ntdll: Connect syscall frames across user callbacks on x86-64. ntdll: Connect syscall frames across user callbacks on i386. ntdll: Add a syscall_cfa member to the ARM syscall frame. ntdll: Add a syscall_cfa member to the ARM64 syscall frame. ntdll: Add a syscall_cfa member to the x86_64 syscall frame. ntdll: Add a syscall_cfa member to the i386 syscall frame. ntdll: Remove unnecessary stack pointer CFI rules. ntdll: Add comments to stack switches in dispatchers. ntdll: Directly access the syscall table variable on ARM64. ntdll: Directly access the syscall table variable on x86-64. ntdll: Store the syscall table in the TEB on ARM. ntdll: Store the syscall table in the TEB on i386.
This merge request has too many patches to be relayed via email. Please visit the URL below to see the contents of the merge request. https://gitlab.winehq.org/wine/wine/-/merge_requests/1088