我对是否可以在exit(3)
调用上调用任意函数感兴趣,这会绕过其他挂钩架构,因此对我来说似乎并不容易。
return
或atexit(3)
声明,显然可以on_exit(3)
,__attribute__((destructor))
或_exit(2)
使用gcc扩展名LD_PRELOAD
替换LD_PRELOAD
;我希望避免有没有办法在没有_exit(2)
的情况下执行此操作,比如覆盖fork(2)
?
编辑:我面临的问题是使用CoW exit(3)
编辑Perl程序。该程序的子进程在exit
调用上运行析构函数,它们触及许多内存位置,导致大量内存复制,尽管它们将退出。
在Perl中使用普通POSIX::_exit
调用很难绕过析构函数,所以一个想法就是调用LD_PRELOAD
。
但是,有一个动态加载的库{{1}},我想在进程退出时调用它中的函数。
答案 0 :(得分:2)
AFAIU,没有LD_PRELOAD
技巧,或ptrace(2)来自另一个进程的PTRACE_SYSCALL
(例如,运行{{1}的父进程})。在最低级别,_exit(2)是system call,因此是" atomic"使用gdb
机器指令进行操作,例如通过vdso(7)。
请注意,C程序可以使用一些SYSENTER
来调用asm
系统调用(或使用间接syscall(2))
假设动态链接到GNU libc或musl-libc的可执行文件,您唯一的方法是捕获exit(3)库函数(不 _exit
系统调用!) atexit(3)
您可以重新定义_exit(2)
,并希望动态链接器会调用_exit
,而不是_exit
中的libc
。我不会玩这样的伎俩。
或者,写一个小包装C程序fork
,execve
和waitpid
原始程序。
答案 1 :(得分:0)
在main()的开头附近调用atexit(),其中包含程序退出时要执行的函数的参数。
你可以多次调用atexit(),从而堆叠应用程序退出时要执行的几件事。