Linux 共享库卸载的钩子函数

Linux 共享库卸载的钩子函数,linux,elf,dynamic-linking,Linux,Elf,Dynamic Linking,我想添加钩子函数,在卸载共享库时将调用该函数。图书馆在Complitation上链接。有可能做这样的事吗?也许gcc有它的标志 我看到了类似的在运行时加载库的解决方案,但它并没有满足我的期望 Solaris和GNU/Linux在其动态链接器中支持LD_AUDIT接口。您需要加载一个auditor模块,该模块实现la_objclose回调函数: 实现可以如此简单: unsigned int la_objclose (uintptr_t *cookie) { printf ("objcl

我想添加钩子函数,在卸载共享库时将调用该函数。图书馆在Complitation上链接。有可能做这样的事吗?也许gcc有它的标志


我看到了类似的在运行时加载库的解决方案,但它并没有满足我的期望

Solaris和GNU/Linux在其动态链接器中支持
LD_AUDIT
接口。您需要加载一个auditor模块,该模块实现
la_objclose
回调函数:

实现可以如此简单:

unsigned int
la_objclose  (uintptr_t *cookie)
{
  printf ("objclose\n");
  return 0;
}

为了确定要关闭的对象,还需要实现
la_objsearch
(可能还有
la_objopen
),以建立一个cookie值,该值以某种方式引用关闭时所需的信息(例如,可以在cookie中存储指向堆分配结构的指针)。

对于Linux系统,
dlopen()
/
dlclose()
手册页解释了如何将此类函数添加到库中:

初始化和终结功能 共享对象可以使用
\uuuuu属性((构造函数))
\uuuu属性(析构函数))
函数属性。构造函数在
dlopen()
返回和析构函数之前执行 函数在
dlclose()返回之前执行。共享对象可能会被删除
导出多个构造函数和析构函数,优先级可以是
与每个函数关联以确定
执行它们的顺序。有关更多信息,请参见gcc信息页面(“功能属性”下)

一种(部分)实现相同结果的旧方法是通过 使用链接器识别的两个特殊符号:
\u init
\u fini
。如果动态加载的共享对象导出名为
\u init()
的例程,则该代码将在加载共享对象后执行 对象,在
dlopen()返回之前。如果共享对象导出
名为
\u fini()
的例程,然后在 对象已卸载。在这种情况下,必须避免链接到 系统启动文件,其中包含这些文件的默认版本; 这可以通过使用gcc(1)
-nostartfiles
命令行来完成 选择权

现在不推荐使用
\u init
\u fini
来支持 前面提到的构造函数和析构函数 优点,允许多次初始化和终结 职能 定义


在编译时链接到的库在程序结束前一直处于加载状态。但在卸载该库时,程序结束前不是有一个小的时间单位吗?我想实现的是在卸载一个特定的库时调用一个特定的函数。您到底想实现什么?难道你不能在主函数的末尾运行有问题的代码吗?