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.
-- v6: ntdll: Remove now unnecessary arch-specific exit frame. ntdll: Avoid calling pthread_exit on thread exit. ntdll: Return entry and suspend from server_init_process_done. ntdll: Create a pthread for the main thread.