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]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]