This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: stderr vs. STDERR_FILENO
Gabriel Dos Reis wrote:
Jonathan Lennox <lennox@cs.columbia.edu> writes:
| Zack Weinberg <zack at codesourcery dot com> writes:
| > For what it's worth I think this is primarily a documentation issue -
|
| It just occured to me -- no, unfortunately, this is a correctness issue.
|
| This C++ program is well-defined by the standard -- it invokes
| std::terminate, which invokes abort().
|
| #include <cstdio>
| #include <stdexcept>
|
| int main()
| {
| std::fclose(stderr);
|
| throw std::runtime_error("Boom!");
| }
|
| However, given a general-purpose C library which complies only with the
| requirements of the C/C++ standards, __gnu_cxx::__verbose_terminate_handler
| invokes undefined behavior on this program.
Which would strongly argue for keeping file descriptor 2.
Why?
As Jonathan pointed out, most (all?) stdio implementations will simply
ignore writes to closed files. In which case, the behavior of the
verose terminate handler, though technically undefined, will be correct.
Writing to file descriptor two after stderr has been closed is
dangerous, independently of any standard. It might really screw up the
system. Not just in an "that behavior is undefined, so the
implementation can erase the disk" kind of way but in a "file descriptor
two might be a special device" kind of way. In other words, it really
might overwrite a disk partition.
If people are determined to avoid stdio, it would be better to get at
the controlling tty and write the message there, in the same way that
some kernels write messages about signals that kill the program. The
controlling tty is at least very unlikely to be a raw disk partition.
The truly safe approach would be to make the verbose terminate handler a
debugging option that users explicitly requested, rather than default
behavior. I'm not necessarily arguing for that, but the safest route --
i.e, the route most likely to fully comply with the standard with the
fewest surprises -- is just to do the one thing the standard requires:
call std::abort.
--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com