微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

加载了 LD_PRELOAD 的库会在最后卸载吗

如何解决加载了 LD_PRELOAD 的库会在最后卸载吗

我正在编写一个内存泄漏跟踪器,并且想在库卸载时打印被跟踪程序中的统计信息。

这个库将与 LD_PRELOAD 技巧一起使用,我们的程序有静态变量会很晚被销毁,所以我想确保统计信息会在程序中的所有静态变量之后打印已销毁,以免误报。

加载了 LD_PRELOAD 的库会在最后卸载吗(晚于被黑程序)?

解决方法

使用 LD_PRELOAD 加载的库会在最后卸载吗

您假设 LD_PRELOADED 库将被卸载,但不能保证这会发生。

这是一个测试用例:

// main.c
#include <unistd.h>

int main(int argc,char *argv[]) {
  if (argc > 1) _exit(0);
  return 0;
}

// preload.c
#include <stdio.h>

__attribute__((constructor)) void init() { fprintf(stderr,"Init\n"); }
__attribute__((destructor)) void fini() { fprintf(stderr,"Fini\n"); }

像这样构建它们:

gcc main.c && gcc -fPIC -shared -o preload.so preload.c

现在观察初始化和终结的顺序:

LD_DEBUG=files LD_PRELOAD=./preload.so ./a.out |& grep 'calling .*ini'
     18310:     calling init: /lib/x86_64-linux-gnu/libc.so.6
     18310:     calling init: ./preload.so
     18310:     calling fini: ./a.out [0]
     18310:     calling fini: ./preload.so [0]

LD_DEBUG=files LD_PRELOAD=./preload.so ./a.out 1 |& grep 'calling .*ini'
     18312:     calling init: /lib/x86_64-linux-gnu/libc.so.6
     18312:     calling init: ./preload.so

请注意,在 _exit() 的情况下,库根本没有最终确定。

另请注意,任何共享库都将依赖于 libc.so.6,因此将在 libc.so.6 之前完成。

但是没有信号或 _exit() 终止,是的:库将以其初始化的相反顺序最终确定(加载和卸载并不是在这里使用的正确术语),这确实意味着 {{ 1}}ed 库将最后完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。