This is the mail archive of the cygwin mailing list for the Cygwin project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello mailing list, I noticed that synchronous signals (e.g., SIGSEGV, SIGFPE) appear to be broken on 64-bit Cygwin systems. I could not find additional information on the mailing list. If this is not already a known problem, you'll find some analysis below. I use Cygwin DLL 2.10 with all packages up-to-date. My test system runs Windows 7. The expected behavior is that an installed signal handler runs exactly once for a signal and the OS terminates the program if the handler returns. This works on 32-bit Cygwin. From my observation, Cygwin 64 differs in the follow ways: 1) Generating a synchronous signal on the main thread, makes the signal handler enter an endless loop. The attached test 'syncsig.c' illustrates this. 2) Generating a synchronous signal on an additional POSIX thread ignores the installed signal handler entirely. The handler does not run and the program gets terminated immediately. The attached test 'syncsig_mt.c' illustrates this. As mentioned, both cases work correctly on 32-bit installations. I cannot point to the exact location of the problem, but it appears that the Cygwin exception-handler code is not set up by 64-bit code. In case 2) I can see the Windows function KiUserExceptionDispatcher() being executed for the synchronous signal on the affected thread. This should lead to a call to the Cygwin exception handler. It does for 32-bit, but not for 64-bit code. From what I've seen, the exception handler is installed in the c'tor exception::exception(). [exception.cc:138] The only invocation I found was in SetThreadName(). [miscfuncs.cc:951] This set-up code is 32-bit-only. BTW, is there a bug tracker for Cygwin? I'd open a bug report there, or add the information to an existing one. Best regards Thomas [exception.cc:138] https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/exception.h;h=ffff7464ba11b5526fcf9d13e32334912a30a3b0;hb=4c73ad6b20378e4b74355fcdb2005f2aac489c9f#l138 [miscfuncs.cc:951] https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/miscfuncs.cc;h=3ad658739ad9e85868ca74ce2e86aa6ddbdbfb37;hb=4c73ad6b20378e4b74355fcdb2005f2aac489c9f#l951 -- Implement thread-safe and fault-tolerant software in C: visit picotm.org -- GnuPG: http://tdz.users.sourceforge.net/tdz.asc Fingerprint: 16FF F599 82F8 E5AA 18C6 5220 D9DA D7D4 4EF1 DF08 Website: transactionblog.org
/* * This test program works on 32-bit and 64-bit Cygwin. On 32-bit * systems, the signal handler runs *exactly* once, which is the correct * behaviour. On 64-bit systems, the exception code enters an endless * loop and the signal handler runs over and over. * * Compile with * * gcc -Wall -O0 -osyncsig ./syncsig.c * * Run with * * ./syncsig * * Expected Result * * Program prints "signal handler running" once * * Actual Result * * On 64-bit systems, the handler runs in an endless loop * */ #include <signal.h> #include <stdio.h> #include <stdlib.h> static void signal_handler(int signum, siginfo_t* info, void* ucontext) { fprintf(stderr, "signal handler running\n"); // unsafe in real code! } int main(int argc, char* argv[]) { struct sigaction act = { .sa_sigaction = signal_handler, .sa_flags = SA_SIGINFO, }; sigemptyset(&act.sa_mask); sigaction(SIGFPE, &act, NULL); /* Trigger Windows Exception for division by zero */ argc /= !argc; fprintf(stderr, "no exception generated\n"); return EXIT_SUCCESS; }
/* * This test program works on 32-bit Cygwin, but fails on 64-bit systems. * Running a signal handler for SIGFPE on the created POSIX thread does * not work. * * Compile with * * gcc -Wall -O0 -pthread -osyncsig_mt ./syncsig_mt.c * * Run with * * ./syncsig_mt * * Expected Result * * Program prints "signal handler running" * * Actual Result * * No output on 64-bit systems, signal handler does not run * */ #include <pthread.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> static void signal_handler(int signum, siginfo_t* info, void* ucontext) { fprintf(stderr, "signal handler running\n"); // unsafe in real code! } static void* thread_start(void* arg) { int argc = *(int*)arg; /* Trigger Windows Exception for division by zero */ argc /= !argc; fprintf(stderr, "no exception generated\n"); return NULL; } int main(int argc, char* argv[]) { struct sigaction act = { .sa_sigaction = signal_handler, .sa_flags = SA_SIGINFO, }; sigemptyset(&act.sa_mask); sigaction(SIGFPE, &act, NULL); pthread_t thread; pthread_create(&thread, NULL, thread_start, &argc); pthread_join(thread, NULL); return EXIT_SUCCESS; }
Attachment:
signature.asc
Description: OpenPGP digital signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |