Email List: Xaustin-group-lX
[All Lists]

Re: AI 42: atexit() and dlclose()

To: Ulrich Drepper <yyyyyyy@xxxxxxxxxx>
Subject: Re: AI 42: atexit() and dlclose()
From: Drazen Kacar <yyyy@xxxxxxxxxxxxx>
Date: Wed, 14 Mar 2001 03:14:30 +0100
Cc: Drazen Kacar <yyyy@xxxxxxxxxxxxx>, Mark Brown <yyyyy@xxxxxxxxxx>, Austin Group <yyyyyyyyyyyyyy@xxxxxxxxxxxxx>
References: <B6D3DFD4.3655%bmark@us.ibm.com> <20010313221943.A23121@washington> <m3g0ghky6g.fsf@otr.mynet.cygnus.com>
Ulrich Drepper wrote:
> Drazen Kacar <yyyy@xxxxxxxxxxxxx> writes:
> 
> > I'd be happier with "Object unloading occurs by a successful invocation
> > of dlclose()." If dlclose() can't or won't unload object (for any reason),
> > it doesn't make sense to run atexit handlers anyway.
> 
> This doesn't work.  The registered functions obviously have to be
> called before you try to unload the object.

Obviously, but dlclose() implementation calls registered functions, right?
Therefore dlclose() can first check if it is OK to unload the object.
If there are no obstacles, it can then call registered functions and
perform unloading.

> So, it is the late if the
> unloading failed (you cannot simply run the constructors again).

I don't expect that an entity external to dlclose() implementation would
interpose here and make unloading fail. Currently I see two interesting
conditions which would prevent removing from process address space (on
implementation that actually does that):

1. Implementation has a way to mark objects as unloadable and dlclose()
   will not remove them from the process space. In this case I think the
   handlers shouldn't be called.

2. Multiple dlopen() calls for the same object. The current dlopen() spec
   says:

      Only a single copy of an object file is brought into the address
      space, even if dlopen() is invoked multiple times in reference to
      the file, and even if different pathnames are used to reference
      the file.

   Suppose there is an application which uses two shared objects (either
   dependencies or through dlopen() calls) and that both objects dlopen()
   yet another object which registers some handlers with atexit().
   What happens when one of the shared objects calls dlclose() for
   this third object? With the current wording, atexit handlers are
   run and one could expect that they would make the object unusable.

   But then the other shared object still has a valid handle and can still
   call functions from the third object. Except that they might not work
   as expected.

   To work as expected, destructor functions in the third object would
   have to check internal reference counter to see if they should
   perform the tear down or do nothing. This is not desirable because 
   there is no portable way to specify initialization function for
   objects used through dlopen(), so object's API would have to
   mandate that the caller explicitly calls such function after dlopen().
   And the whole thing is error prone, because things like this tend
   to be overlooked.

Both of the above conditions are detected by the dlclose() implementation
and it can decide whether to call object's destructor functions or not.
I would like it to perform reference counting and permission checking,
so loadable objects wouldn't have to do it.

My wording is no good, because it doesn't cover the second case, since
dlclose() will return success to both invocations.

BTW, it would be nice if there was a portable way to specify
initialization function(s) for shared objects. I don't know if that's
in scope, though.

-- 
 .-.   .-.    Sarcasm is just one more service we offer.
(_  \ /  _)
     |        yyyy@xxxxxxxxxxxxx
     |

<Prev in Thread] Current Thread [Next in Thread>