[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: undefined behavior in closeout, aggravated by libsigsegv
From: |
Bruno Haible |
Subject: |
Re: undefined behavior in closeout, aggravated by libsigsegv |
Date: |
Sat, 18 Jul 2009 09:03:53 +0200 |
User-agent: |
KMail/1.9.9 |
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