Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: atexit(), dlclose() and more atexit()



    Date:        Tue, 30 Jun 2020 13:43:00 +0200
    From:        Kamil Rytarowski <kamil%netbsd.org@localhost>
    Message-ID:  <d3967880-2bfb-c289-5188-89f95e626725%netbsd.org@localhost>

I had been ignoring this discussion, but on cleaning up some
unread list e-mail, I saw this nonsense, and this is just going too far.

  | This is an extension and extensions are allowed.

That's absolutely true, but that doesn't relieve the implementation of
the need to follow what the standard does require.

And in this case that is:

	At normal program termination, all functions registered by the
	atexit( ) function shall be called, in the reverse order of their
	registration,

That is, when the program ends, *every*  function registered by atexit()
must be called - there is nothing there which ever suggests "except if it
has already been called".  That isn't there, because atexit() functions
are only expected to be called when the process exits (code can explicitly
call such a function, independently, if it wants to of course).

Not only must the functions be called, the order in which they are to be
called is specified, so if program does atexit(A), then dlopen(L), and in
the init function for L, we get atexit(B), after which (after the dlopen and
the init functions are done) the program does atexit(C), then at
program termination time, the atexit processing must call C, and then B,
and then A; B must not be called (as part of atexit processing) before C.

I really cannot see how you can possibly mangle the operations and remain
compliant with the standard (nor how any other implementation can).

In another message kamil%netbsd.org@localhost said:
  | Technically atexit() != __cxa_atexit(), but the "atexit-registered function"
  | mechanism is in place and defined for early DSO unload in C++. 

No-one cares who invented what when, but the very existence of
cta_atexit (which not just technically is != atexit, it simply
isn't atexit) would be because atexit() could not be sanely coerced
to work for the purpose intended.   Don't you think that if atexit()
would work, they wouldn't simply have used it, instead of inventing
a new (similarly named) function for the purpose?

Back to the initial message:
  | Another option would be to make dlclose() no-op and keep atexit(3)
  | operational, but this is certainly not what we want.

Actually, that one is a possible solution.  dlclose() is not required
to do anything at all.   While having it never do anything isn't what
we'd want, having it do nothing if there is a pending atexit function
from the dynamic object (or even simply one registered by the dynamic
object - though the problematic case, as I understand it, is when the
function has been removed and so can no longer sensibly be called) is
not a ridiculous suggestion.

If a dynamic library has registered an atexit function, its obvious
intent is that it will remain loaded until the program exits, and so
in that case making dlclose(), if called, do nothing seems like an
entirely sensible idea.

kre



Home | Main Index | Thread Index | Old Index