[RFC] libgfortran dll i/o redirection lossage caused by order-of-termination issue

Corinna Vinschen corinna-cygwin@cygwin.com
Thu Jul 9 08:53:00 GMT 2009

On Jul  8 19:43, Christopher Faylor wrote:
> On Wed, Jul 08, 2009 at 10:48:36PM +0100, Dave Korn wrote:
> >    Hippos,
> >[...]
> >  Now, in this sequence of events, first we call the atexit hooks, which
> >includes all static dtors:
> >
> >> void
> >> _DEFUN (exit, (code),
> >> 	int code)
> >> {
> >>   __call_exitprocs (code, NULL);
> >
> >... then we call newlib cleanup ...
> >
> >>   if (_GLOBAL_REENT->__cleanup)
> >>     (*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT);
> >
> >... then we terminate the loaded DLLs:
> >
> >>       dll_global_dtors ();
> >
> >  That's bad.  The call to newlib's __cleanup() hook shuts down stdio
> >facilities, and so when libgfortran DLL's dtors are finally called, they
> >attempt to flush the buffer down already-closed stdio channels, and it gets
> >silently dropped on the floor.
> Yep.  Longstanding issue.  I thought you couldn't guarantee that a
> global destructor would be able to do I/O.

What speaks technically against calling _GLOBAL_REENT->__cleanup after

> [...]
> >so on the face of it, I'm wondering if we should hook dll finalisation
> >into newlib's atexit mechanism somehow/where, rather than running it
> >later on.  We already do this for do_global_dtors, which gets invoked
> >from __call_exitprocs().  Another feasible alternative would be to
> >provide our own definition of exit(), overriding newlib's.
> [...]
> You can't hook important things destructors into atexit() since my
> reading of the linux man page at least (I sense a looming authoratitive
> POSIX citation coming) says that hooks only get called when a function
> calls exit, not when a function calls _exit.  I believe that dtors
> should always be called unless the program is being terminated by a
> signal.

I'm wondering if that's really the case.  Take the flushing of streams.
Per POSIX (you asked for it) when you call _exit then "Open streams
shall not be flushed".  But that would be exactly what the dtors of the
fortran library will do when they are called.

That's just an example of course, but the dtors function of a library
are usually responsible for the graceful exit, doing the high-level
cleanup stuff.  But that's exactly not what _exit is supposed to do.
The idea is an immediate process exit with only the OS-specific cleanup
like closing file descriptors.  Which is Cygwin's job only.  As a
worst-case scenario, the dtors function of a database library should
not be covered by _exit, afaics.


Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

More information about the Cygwin-developers mailing list