Hi Eric, > I've traced it to the fact that m4 uses the closeout module, which does the > following: > > calls close_stream (stdout) > => fclose (stdout) > detects that pending data was lost, so call error() > => fflush (stdout) > > According to POSIX, using stdout after it has been passed to fclose is > undefined behavior.
Yup. We did not detect this bug earlier because on most systems, fflush returns -1/EBADF in this situation, rather than crashing. > What's the best way to do that? Have > close_stdout call freopen("/dev/null","w",stdout) prior to calling error()? Yes, this looks like the right fix to me. With "/dev/null" being replaced with DEV_NULL defined as in lib/pipe.h, for mingw portability. > Convince the glibc folks to change error() to not call fflush(stdout) if > fileno > (stdout) is closed? This would not help: After fclose (stdout), "any use of stdout results in undefined behavior", says POSIX, hence fileno (stdout) is already undefined behaviour. > Rewrite close_stdout to open-code the error-printing > actions instead of calling error()? That would go against the goal of consistent error reporting. Some tools (like emacs) analyze the error output of a program and rely on the expected formatting of error messages. > there is currently a > thread on the cygwin list about a crash under Windows 2008 R2 64-bit, where > Windows has tightened the rules on what forms a valid SEH exception chain and > the cygwin handler was violating those rules; and that thread has also raised > the concern that libsigsegv may be making the same mistakes by trying to > override cygwin's handler: > > http://cygwin.com/ml/cygwin/2009-07/msg00630.html > http://cygwin.com/ml/cygwin/2009-07/msg00635.html The mail at http://cygwin.com/ml/cygwin/2009-07/msg00607.html indicates that the problem was with incorrect nesting of SEH exception chain additions/removals. The values of the addresses in that chain appear to be irrelevant. Thus it does not matter whether libsigsegv is compiled as a DLL or statically. At least that's what I understand from the thread. Bruno