top | item 36798205

(no title)

zwp | 2 years ago

Tangential question: there is one reason to use NODELETE in the dlopen(3) man page: https://man7.org/linux/man-pages/man3/dlopen.3.html

  RTLD_NODELETE (since glibc 2.2)
    Do not unload the shared object during dlclose().
    Consequently, the object's static and global variables
    are not reinitialized if the object is reloaded with
    dlopen() at a later time.
Are there any other times when it's beneficial to use NODELETE?

discuss

order

fweimer|2 years ago

You mean as opposed to never calling dlclose to the handle? If you specify RTLD_NODELETE, the dynamic linker can avoid some dependency tracking that would otherwise be needed to avoid premature unloading of the object because that unloading can never happen.

However, the main application of NODELETE is the DF_1_NODELETE flag in the shared object itself. A typical use case is if the shared object installs a function pointer somewhere where it cannot be reverted as part of the dlclose operation. If the dlclose proceeds despite this, calling the function later will have hard-to-diagnose, unpredictable consequences. Rather than relying on dlclose never being called (which is difficult because the object might have been loaded as an indirect dependency, unaware to the caller of dlopen), using the DF_1_NODELETE flag makes this explicit.

rwmj|2 years ago

It's not really possible to safely unmap code in a library in the presence of various other useful features you might like to use, specifically thread-local storage, atfork, callbacks (and probably threads in general). Libvirt started to use this flag over a decade ago: https://libvir-list.redhat.narkive.com/TUbaBTsk/libvirt-patc...