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

Christopher Faylor cgf-use-the-mailinglist-please@cygwin.com
Thu Jul 9 19:49:00 GMT 2009

On Thu, Jul 09, 2009 at 10:53:16AM +0200, Corinna Vinschen wrote:
>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

Right now, _GLOBAL_REENT->__cleanup is called by newlib's exit.  So we'd have
to preemptively call it somewhere.  Where would that be?  Do we move the
running out of the dtors out of do_exit()?

>> [...]
>> >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.

True, and that makes me wonder about the fortran implementation.


More information about the Cygwin-developers mailing list