Eric Blake <ebb9 <at> byu.net> writes: > > How can I reproduce it? > Meanwhile, I will try to spend some time inspecting cygwin source code to > see if I can find another example of an internal fault that cygwin expects > to handle, and where libsigsegv intercepting the fault can cause > observable behavior changes, beyond just EFAULT handling.
Here's a relatively simple example. POSIX 2001 states pthread_attr_init may fail with EBUSY if an object was previously initialized. (Reliably testing whether an object was previously initialized turns out to be a relatively hard problem, so POSIX 2008 relaxed the specification by removing the 'may fail' of EBUSY if x is already initialized, under the cop-out that such behavior was already explicitly undefined, so an implementation may choose to do something simpler than fail with EBUSY; however, in the rationale, it still states that implementations are still encouraged to do an EBUSY check if feasible). This example flushes out the libsigsegv interaction for both cygwin 1.5 and today's CVS cygwin 1.7. $ cat foo.c #include <unistd.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <sigsegv.h> int handler (void *addr, int bad) { exit (2); } int main (int argc, char **argv) { pthread_attr_t a; memset (&a, 1, sizeof a); pthread_attr_init (&a); if (1 < argc) sigsegv_install_handler (handler); pthread_attr_t b; memset (&b, 1, sizeof b); pthread_attr_init (&b); return 0; } $ gcc -o foo -Wall -g foo.c -lsigsegv $ ./foo; echo $? 0 $ ./foo 1; echo $? 2 The way that cygwin implements EBUSY validation is by probing the contents of the pthread_attr_t to see if it is already initialized (that is, does the pointer contain the magic cookie put in place during initialization and removed during pthread_attr_destroy). But since the object can be stack-allocated, and thus contain random bytes (simulated in the above example with the explicit memset to make the example more repeatable), that probe can fault. In this case, a fault is a GOOD thing - it means that the object is NOT already initialized, so cygwin silently ignores the fault and lets pthread_attr_t succeed. But if libsigsegv is compiled without --enable-EFAULT, it interferes with POSIX compliance. Search for verifyable_object_isvalid in: http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/thread.cc? rev=1.216&content-type=text/x-cvsweb-markup&cvsroot=src -- Eric Blake