You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何预加载至dash的共享库fini函数未被调用?

为何dash中共享库的卸载函数fini未被调用?

环境与测试代码

使用最新版本的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

测试结果:共享库的加载函数init被正常调用(生成了init文件),但卸载函数fini未被调用(未生成fini文件)。若将dash替换为bash,两个函数都会被触发执行。即使改用__attribute__((destructor))标记终止函数,dash下仍不会调用。

补充系统信息

$ 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)

原因解释

dash作为轻量级shell,为了极致的性能和资源占用优化,在进程退出时直接调用*_exit()系统调用,而非标准C库的exit()*函数。

  • *exit()*函数会触发完整的用户态清理流程:包括调用所有已注册的atexit处理函数、刷新stdio缓冲区,以及通知动态链接器调用共享库的终止函数(fini段或__attribute__((destructor))标记的函数)。
  • _exit()则会直接向内核请求终止进程,跳过所有用户态的清理操作,动态链接器没有机会执行共享库的卸载逻辑,因此fini函数不会被调用。

内容的提问来源于stack exchange,提问作者Mark Galeck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:22:53