Hello! The current implementation of atexit and dlclose allow programs to be shot in the tail by dlclose-ing a shared library, which may contain an atexit-scheduled function. In this case the program will seg-fault upon otherwise clean exit. Although usually benign, this may prevent other atexit-registered functions from ever being called -- potentially causing far more disruption than a random core-dump file here and there. Our current attitude is "atexit should not be called from shared libraries. Ha-ha." Although this is, likely, true, we could do better -- the atexit-scheduled function can be looked up in the list of the dlopen-ed libraries (by scanning the linked list and checking, whether the passed pointer is between mapbase and mapbase+textsize of any of the Obj_Entries). Here are the approaches I can think of: 1. atexit to bump up the shared object's ref-count. A re-implementation of atexit() (under libexec/rtld-elf someplace) will scan through the dlopen-ed objects. If the atexit's argument is found to belong to an object, that object's dl_refcount will be increased. This will cause the object to survive the explicit dlclose(), although it may still not survive, if the application calls dlclose an extra time. 2. dlclose to refuse unloading the object This way it will be the dlclose, that will perform the check -- for each symbol registered through atexit, it will check, whether the shared object being closed owns the symbol and fail with a descriptive error dlerror (and warnx?), if it does. I personally favour the second approach more, because it provides for more descriptive diagnostics and requires less invasive implementation (no atexit re-implementation). It will also survive multiple calls to dlclose, thus being more helpful to erroneous programmers. I can see, however, how the first approach can be argued to be "more elegant", though... What do you think? -miReceived on Tue Aug 14 2007 - 16:10:46 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:16 UTC