如何在Linux中检查信号处理程序

时间:2018-07-27 02:09:58

标签: c linux shell linux-kernel

我已阅读此讨论,讨论如何检查每个过程的信号动作: How can I check what signals a process is listening to?

但是,我想使用C / C ++,Python或其他方式来获取每个进程的信号处理程序名称的用户空间。就像Solaris中的psig一样: What is the meaning of every column when executing psig command?

在Linux中可以做到吗?

1 个答案:

答案 0 :(得分:1)

由于Linux内核未公开信号处理程序(除了在进程本身中使用sigaction()(或signal())syscall外,您需要将可执行代码注入目标进程中以获得此信息。

(或者,或者创建一个公开此信息的Linux内核模块。)

因此,这绝对是一个 问题。

请注意,不可能始终获得函数的名称,因为可以在没有二进制文件中任何特定名称的情况下声明处理程序static void


最简单的方法是使用ELF构造函数(与C ++不相关;创建一个动态库来插入signal()sigaction(),在Linux中,ELF二进制文件仅支持标记函数“ constructor”,在main()之前,它们会自动执行,然后以只写追加模式打开一个合适的日志文件,例如/var/log/sighandlers/PID.log,并转储/proc/self/maps的内容以记录二进制地址插入。然后插入的函数将简单地将新分配的处理程序的地址写入日志文件。

请务必注意,sigaction()signal()均为async-signal safe functions,因此插入的版本也应为。 (幸运的是,您只需要write(),这是安全的异步信号。我建议使用dlsym()在ELF构造函数中查找原始函数指针。)

在检查日志文件时,应相对于二进制映射的开头计算函数地址,然后使用objdump -tT binaryobjdump -d binary来查找该地址所属的符号。

我个人不会打扰任何其他方法,即使这需要使用一种特殊的命令(设置LD_LIBRARY_PATH)来执行每个二进制程序以找出它们;要么就是那个,要么就是内核模块。