On Tue, Jun 30, 2020 at 13:43:00 +0200, Kamil Rytarowski wrote:

> On 30.06.2020 05:16, Jason Thorpe wrote:
> > 
> >> On Jun 29, 2020, at 5:13 PM, Kamil Rytarowski <ka...@netbsd.org> wrote:
> >>
> >>> <quote>
> >>> The atexit() function shall register the function pointed to by func, to 
> >>> be called without arguments at normal program termination. At normal 
> >>> program termination, all functions registered by the atexit() function 
> >>> shall be called, in the reverse order of their registration, except that 
> >>> a function is called after any previously registered functions that had 
> >>> already been called at the time it was registered. Normal termination 
> >>> occurs either by a call to exit() or a return from main().
> >>> </quote>
> >>>
> >>> My reading of the standard here is that atexit() handlers are called at 
> >>> "normal program termination", and that "normal program termination" is 
> >>> explicitly defined as either a call to exit() or returning from main(), 
> >>> and thus any other call to atexit() handlers is expressly forbidden by 
> >>> the standard.
> >>>
> >>
> >> There is no word "only", so it's unspecified.
> > 
> > Sorry, but that seems like a huge stretch.  Everything seems tied to the 
> > process "exit" path in the description of atexit().  Even in the 
> > APPLICATION USAGE section, they have the following informative text:
> > 
> > <quote>
> > All functions registered by the atexit() function are called at normal 
> > process termination, which occurs by a call to the exit() function or a 
> > return from main() or on the last thread termination, when the behavior is 
> > as if the implementation called exit() with a zero argument at thread 
> > termination time.
> > </quote>
> > 
> > ...specifically, the "is as if" qualifier.  In my reading, if the enclosing 
> > program is not terminating, then atexit() handlers should not be called.
> > 
> > dlclose() does not initiate "normal program termination" (it's also 
> > specified in Issue 7, so I double-checked!), nor does it mention anything 
> > about being considered "normal program termination" from the perspective of 
> > the shared object that is being closed.
> > 
> > Can you point to another place in the standard that uses the "only" type 
> > wording to justify your reading of atexit()?
> > 
> 
> This is an extension and extensions are allowed.
> 
> There is also no better alternative as __cxa_atexit() besides of being
> C++ ABI specific, it is documented as internal only:
> 
> "No user interface to __cxa_atexit is supported, so the user is not able
> to register an atexit function with a parameter or a home DSO."
> 
> https://itanium-cxx-abi.github.io/cxx-abi/abi.html
> 
> This is only me, but DSO can be treated as a subprogram loaded after
> dlopen() and terminated upon dlclose(). atexit(3) in this metaphor
> naturally associates to dlclose().

That's an enticing line of reasoning, and yes one can see how it
caused the current atexit abuse (heck, I would have done it myself,
people are lazy :), but as all analogies it can only be taken so far.
A program termination means the program will be gone very soon, it's
memory freed, file descriptors closed, etc.  In contrast, the program
continues to work after dlclose, so resource leaks are a real concern.
So cleanup code that runs at exit time and at the dlclose time have
very different operational constraints.  atexit-for-dlclose really
pushes you further back into MSDOS-like environment where programs are
not insulated from each other.

-uwe

Reply via email to