This is the mail archive of the
cygwin
mailing list for the Cygwin project.
fun? with libsigsegv
- From: Eric Blake <ebb9 at byu dot net>
- To: cygwin at cygwin dot com
- Date: Fri, 17 Jul 2009 22:07:53 +0000 (UTC)
- Subject: fun? with libsigsegv
This post is so cgf can exhale his bated breath from his recent commit:
http://sourceware.org/cgi-bin/cvsweb.cgi/winsup/cygwin/cygtls.cc.diff?
cvsroot=uberbaum&r1=1.68&r2=1.69
[By the way, that commit added changes to pipe handling without a ChangeLog
entry; is it ready for prime-time yet?]
First, the STC:
$ cat foo.c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef libsigsegv
#include <sigsegv.h>
int
handler (void *addr, int bad)
{
abort ();
}
#endif
void
die ()
{
int i;
i = fclose (stdout);
fprintf (stderr, "fclose %d, errno %d\n", i, errno);
errno = 0;
i = fflush (stdout);
fprintf (stderr, "fflush %d, errno %d\n", i, errno);
}
int main ()
{
close (1);
atexit (die);
#ifdef libsigsegv
sigsegv_install_handler (handler);
#endif
fputc ('1', stdout);
return 0;
}
Pre-patch - this is with stock cygwin-1.7.0-51 and libsigsegv-2.4-1 (upstream
libsigsegv is at 2.6, but I've checked that none of the upstream changes since
2.4 affect cygwin; it helps that I've written some of the upstream changes).
In a way, the STC is relying on undefined behavior (POSIX says that the use of
fflush(stdout) after fclose(stdout) is unspecified), but every other system
I've tried handles this gracefully (although not consistently).
$ gcc -o foo foo.c -lsigsegv
$ ./foo
fclose -1, errno 9
fflush 0, errno 0
No libsigsegv in the mix, and we don't detect any error (other platforms
return -1 and/or set errno - the best would be doing both, rather than cygwin's
approach of claiming success). Single stepping through fflush, it looks like
we may be inadvertently faulting while dereferencing the closed stream, but
that the fault is caught by cygwin (as part of _sigfe?) and silently ignored.
$ gcc -o foo foo.c -lsigsegv -Dlibsigsegv
$ ./foo
fclose -1, errno 9
Aborted (core dumped)
Ouch - adding libsigsegv into the mix meant that the internal fault is now
trapped by libsigsegv before cygwin gets a chance to look at it, and turned
into an abort. Proof positive that libsigsegv's mucking around with the SEH
chain is not nice.
Now, upgrade to the latest snapshot, 20090717.
Without libsigsegv, things operate as before. But with libsigsegv, I now see...
wait for it...
(Sorry for dragging this on, but you DID say you were waiting with bated
breath. :)...
$ ./foo
fclose -1, errno 9
fflush 0, errno 0
That is, libsigsegv no longer causes an unwanted abort. And the latest
libsigsegv.git package still passes 'make check'. So in other words, it looks
like you fixed a real bug, and without causing any regressions to libsigsegv
(at least, none identified so far, although the upstream testsuite could
probably test more cases)! Thanks!
Meanwhile, I am considering working on a newlib patch that changes fflush to
immediately die with EBADF rather than trying to _flockfile(fp) if fp->_flags
is 0, if for no other reason than to be more like Linux in returning EBADF
instead of success on my unspecified STC.
--
Eric Blake
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple