http://bugs.winehq.org/show_bug.cgi?id=20380
--- Comment #74 from Michael Builov mbuilov@gmail.com 2010-02-13 13:30:49 --- Created an attachment (id=26243) --> (http://bugs.winehq.org/attachment.cgi?id=26243) source code of test program
(In reply to comment #73) The calls from wine. I don't see any direct Lock called from Homm3.
In the game there are two threads: one thread draws via bitblt (which segfaults), other thread - a timer, which suspends first thread sending him SIGUSR1. It is segv_handler from ntdll.dll.so who messes up with registers saving and then restoring context of faulting thread. "nested exception" occurs when timer thread suspends first thread while it is in segv_handler.
To fix the bug it's needed to block SIGUSR1 in segv_handler, which is normally done at signal handler installation - man sigaction, see sa_mask. In wine signal handlers installed in wine-1.1.38/dlls/ntdll/signal_i386.c, in function signal_init_process(). But setting sa_mask is not enough, if threads created by pthread_create() then pthread_kill() should be used to send signals, not just kill(), otherwise signals may not be blocked correctly.
I've attached source code of program to test signal handling. The program may run on x86 or x86_64. - to test pthread_kill(), compile the program by "gcc -DUSE_PTHREAD_KILL sig_test.c -lpthread -o sigtest" - to test kill() - by "gcc sig_test.c -lpthread -o sigtest"
After running ./sigtest you will see that kill() works incorrectly and pthread_kill() is fine.