https://bugs.winehq.org/show_bug.cgi?id=52213
--- Comment #11 from Giovanni Mascellani gmascellani@codeweavers.com --- I think I'm getting an idea of what is happening here: when a thread is started, its stack pointer is stored in amd64_thread_data()->exit_frame by signal_start_thread() and syscall_frame is used whenever the execution flow is in a UNIX library. When exiting a thread, signal_exit_thread() resets the stack to the exit_frame and then calls pthread_exit().
The problem is that pthread_exit() doesn't like this arrangement: basically the only thing pthread_exit() does is unwinding the thread's stack, so that all cleanup procedures, registered for example with pthread_cleanup_push(), are executed. But since we already unwound the stack under its feet (and possibly rewrote a part of it inside the SIGQUIT handler), this doesn't work anymore.
In the particular case on my test program, inside pthread_cond_wait() a cleanup procedure is established (to properly abort the wait if the stack is unwound), and since its address is overwritten inside the SIGQUIT handler, a segmentation fault happens.
I am not sure of what is the correct way to fix this problem. I'd be tempted to say that we can do away with exit_frame and just let pthread unwind the stack, but I am not sure what exit_frame is supposed to help with. Why aren't we using the stack allocated by pthread, instead of transitioning to our own syscall stack?