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

Christopher Faylor cgf-use-the-mailinglist-please@cygwin.com
Fri Jul 10 03:27:00 GMT 2009

On Fri, Jul 10, 2009 at 12:43:44AM +0100, Dave Korn wrote:
>Christopher Faylor wrote:
>>>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.
>Do you have a reference?  I couldn't see anything in gABI, n2800 or
>cxx-abi that really obviously looked like it said that to me.

I couldn't find one either.  I can't remember if this is something I
read or something I just felt we had to live with.  I think it's
probably the latter.

>> I've fiddled with this code on and off for twelve years now and run into
>> the "newlib issue" a couple of times.  This is one of those places where
>> I habitually say "Why are we using newlib anyway?" It's one of those
>> places where you want the newlib library to somehow know more about
>> Cygwin.
>> 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 may be misinterpreting it, but n2800#
>"  Calling the function std::abort() declared in <cstdlib> terminates the
>program without executing any destructors and without calling the functions
>passed to std::atexit() or std::at_quick_exit().  "
>suggests to me it's ok.  abort() really is a quick bail-out, I think.
>Corinna Vinschen wrote:
>> What speaks technically against calling _GLOBAL_REENT->__cleanup after
>> dll_global_dtors?
>Christopher Faylor wrote:
>> 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()?
>  I think that could well be the solution.  DLL dtors should be handled by
>atexit functionality exactly like the global dtors.
>Corinna Vinschen wrote:
>> 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.
>Christopher Faylor wrote:
>> True, and that makes me wonder about the fortran implementation.
>  I think the fortran implementation is entirely within its rights.  The
>fortran runtime for the application exits via exit(), not _exit(), and so it
>expects its destructors to get run - and since _exit() doesn't run dtors, it
>expects them to be run before _exit().
>says clearly that first atexit() functions are run, then file descriptors are
>closed.  It doesn't talk about C++ dtors of course, but the cxx-abi says that
>__cxa_atexit is required for full ABI conformance, and this must be why; so
>that an integrated mechanism can be used for all destruction, and the language
>runtime doesn't have to worry about when .dtors sections get run.
>  Libfortran on the other hand uses an explicit __attribute__((destructor)) on
>the shutdown function.  It should probably be using an atexit registration.
>  So... I think the thing I'm going to try is indeed removing
>dll_global_dtors() from do_exit(), and I'm going to add an "atexit
>(dll_global_dtors)" in __main(), and see how that goes.
>  (Also, as a future improvement, implementing __cxa_atexit and making
>dlopen/dlclose aware of it might be a good trick).

Ok, sounds like a plan.

My only request is that *this time* we add volumnious documentation with
references.  Oh how I wish I could time travel back and knock myself
over the head with this simple requirement.


More information about the Cygwin-developers mailing list