atexit vs. dlclose
Mikhail Teterin
mi+current at aldan.algebra.com
Tue Aug 14 11:10:46 PDT 2007
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?
-mi
More information about the freebsd-current
mailing list