如何从进程中卸载所有相关的共享库?

时间:2017-08-30 11:34:23

标签: linux dynamic-linking shared-libraries

我创建了一个共享库libA.so,使用dlopen()动态加载到进程中。 libA.so还链接到其他共享库libB.so和libC.so. 因此,当我使用dlopen()加载libA.so时,依赖的共享库libB.so和libC.so也会加载到进程中。

我可以使用命令cat / proc / PID / maps

将库libA.so,libB.so和libC.so加载到进程中

在使用dlclose()卸载libA.so期间,将从进程中卸载库libA.so。但是不会从进程中卸载库libB.so和libC.so。

从cat / proc / PID / maps,我可以看到libA.so被卸载但是libB.so和libC.so仍然退出。

如何从进程中卸载依赖共享库libB.so和libC.so?

1 个答案:

答案 0 :(得分:0)

  

如何从进程中卸载依赖共享库libB.so和libC.so?

您需要先了解在dlclose libA.so时未卸载这些库的原因。

有几个可能的原因:

  1. 其中一个或两个库可能标有NODELETE标志。
  2. 其中一个或两个库可能已使用其符号。
  3. 要检查#1,请执行以下操作:

    readelf -d libB.so libC.so | grep NODELETE
    

    如果这导致非空输出,则已告知动态加载程序不卸载库,并且您无法执行任何操作。

    检查#2更难。 #2的一种方式可能发生在例如libB.so初始化程序从libB.so注册atexit的函数。如果允许卸载库,则atexit保留的函数指针将变为悬空状态,并且调用exit将会崩溃。

    使用GLIBC时,您可以要求加载程序使用LD_DEBUG=bindings ./a.out打印符号解析信息。这将产生大量输出,这应该允许您找出来自例如libB.so受到约束。这可能足以猜出为什么libB.so没有被卸载。