我使用的是最新的Ubuntu Linux。
下面是一个共享库,其中包含加载和卸载时调用的函数:shared.c
:
#include <fcntl.h>
#include <sys/stat.h>
void init() {
open("init", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
}
void fini() {
open("fini", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
}
这是用gcc -shared -fPIC -Wl,-init=init -Wl,-fini=fini shared.c -o shared.so
然后我这样做:
$ rm init fini
$ LD_PRELOAD=$PWD/shared.so dash /dev/null
$ echo $?
0
$ ls init
init
$ ls fini
ls: cannot access 'fini': No such file or directory
因此...调用了加载函数,但未调用卸载函数
如果我用bash
替换dash
,两个都被调用。
使用__attribute__((destructor))
没有什么区别。
为什么不调用dash
的卸载函数?
根据Marco Bonelli的要求添加:
$ file $(which dash)
/usr/bin/dash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f7ab02fc1b8ff61b41647c1e16ec9d95ba5de9f0, for GNU/Linux 3.2.0, stripped
$ ldd $(which dash)
linux-vdso.so.1 (0x00007ffd931c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6b19e84000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6b1a0ec000)
2条答案
按热度按时间ws51t4hk1#
为什么共享库fini函数在预加载到dash时没有被调用?
因为dash在这里调用
_exit
,_exit
在这里调用exit_group syscall,syscall立即终止程序。我们再举一个小例子:
执行时不输出停止:
6vl6ewon2#
我应该把这作为一个评论,但我把它作为一个答案的格式的目的。
问题不在于
redirection
和touch
之间的区别,因为在dash/touch运行中,shared.so被加载了两次,一次用于dash,一次用于touch。fini
仅与touch
一起触发。您可以看到这两次运行的差异:
所以这和
dash
有关。希望能为您的调查提供更多的资料。