On 30.06.2020 15:49, Valery Ushakov wrote: > On Tue, Jun 30, 2020 at 15:09:14 +0200, Kamil Rytarowski wrote: > >> On 30.06.2020 14:24, Valery Ushakov wrote: >>> 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 <kamil%netbsd.org@localhost> 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. >> >> Dynamic loading and unloading code predates MSDOS. It also predates >> shared libraries in UNIX (e.g. Lisp C bindings, predating MSDOS). > > What are you even talking about?! You go out of your way to > misinterpret ~anything said to you and/or to put/steer it into the > context that was obviously not intended. If talking to you requires > math like precision in specifying every tiny detail then expect people > to dissmiss you and your arguments regardless of whatever technical > merits they might have. > > Subprograms are not the invention of MSDOS and predate them. This feature was available in other OSs like BeOS. atexit() as a mechanism can be newer. >> atexit-for-dlclose is already done in C++ behind the scenes for Objects >> and nobody calls it MSDOS-like environment (even if it is, it's not a >> bad design). > > Two can play that game... What does that sentence mean? Which c++ > implementation are you talking about? What specific aspect of that > implementation do you refer to as atexit-for-dlclose? Please provide > specific examples. > > The already linked page from Itanium C++ ABI documents this: 3.3.6.3 Runtime API Object construction: After constructing a global (or local static) object, that will require destruction on exit, a termination function is registered as follows: extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); This registration, e.g. __cxa_atexit(f,p,d), is intended to cause the call f(p) when DSO d is unloaded, before all such termination calls registered before this one. It returns zero if registration is successful, nonzero on failure. Technically atexit() != __cxa_atexit(), but the "atexit-registered function" mechanism is in place and defined for early DSO unload in C++.
Attachment:
signature.asc
Description: OpenPGP digital signature