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 <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. >> >> 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++.
signature.asc
Description: OpenPGP digital signature