Dav*_*ing 5 destructor shared-libraries exit dlopen
进程中的动态对象有多种来源:
DT_NEEDED对于 ELF)dlopen或类似的)在任何一种情况下,它们都可以显式( dlclose) 或在进程运行它们的终结(函数、C++ 中的静态持续时间析构函数和函数)时隐式卸载。exitatexit__attribute__((destructor))
在这些不同的情况下,是什么决定了动态对象初始化和结束的顺序?显然,dlclose库的最后一个会立即卸载它,但是它的依赖关系树(其中一些也可能是其他加载的库的依赖关系)呢?如果库被dlopen编辑但随后被卸载exit怎么办?
我倾向于期望通常的初始化顺序相反,但也许两者之间存在差异DT_NEEDED,dlopen因为“插件”是由后者加载的,并且可能依赖于可执行文件的数据而不是相反。
该算法在所有情况下都是相同的。映射主可执行文件(或dlopened 库)后,动态链接器将按拓扑顺序执行初始化函数,以便依赖项在依赖项之前初始化。请注意,在某些情况下,这可能会导致未指定顺序,并且链接器会做出任意选择。
库析构函数在其构造函数之一中注册(通过调用__cxa_atexit)。注册是通过将累积库 dtor 函数添加到 Glibc 内的特殊列表中来执行的。在 上exit,列表向前遍历,因此依赖的析构函数将在其依赖项之前被调用。