Cra*_*ild 0 c shared-libraries
所以我正在研究共享库,我读到dlclose()在进程终止时执行隐式。我想知道谁负责这个电话。例如,如果我写:
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后如果我这样做了,ldd ./a.out我会得到这些库的列表:
linux-vdso.so.1 => (0x00007ffd6675c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2569866000)
/lib64/ld-linux-x86-64.so.2 (0x0000562b69162000)
Run Code Online (Sandbox Code Playgroud)
链接器负责加载这些权限,那么./a.out对于dlclose()这些库的隐式,在终止此可执行文件时谁负责?
我没有 Kerrisk 的书,但如果你准确地描述了它的内容,那么它们似乎有点简化。严格地说,无论何时一个进程终止,dlclose()都会为其每个打开的共享库调用该函数,但可以合理地说,每当一个进程终止时,它在打开的共享库上的所有句柄都将关闭。因此,操作系统会识别出每个共享库引用的进程少了一个,如果这使任何共享库的引用计数为零,那么操作系统可能会选择从内存中卸载它们。
dlclose()做更多的工作。特别是,它会导致库中的任何析构函数运行。当进程通过从 返回main()或通过调用正常退出时,这些函数也将运行exit(),但如果进程以其他方式终止,例如调用_exit()或响应接收信号,则不会运行。在正常退出的情况下,净效果可能与dlclose()为每个打开的共享库调用一样,但即便如此,也不一定通过实际调用dlclose().
最后,请注意,虽然dl*()函数是由 POSIX 定义的,但动态/共享库的基本上所有细节都由实现自行决定。由于您询问了一本 Linux 书籍,因此我引用了一些特定于 Linux 的细节。
我怀疑这本书只是谈论调用exit()或返回时的正常进程终止main()。dlopen()大概注册了一个atexit()执行动态库的所有终止函数的处理程序。
当进程异常终止时,库无法执行任何代码。如果进程被操作系统终止而不是正常退出,则操作系统只会释放任何文件句柄,但不会在进程上下文中执行代码。