proc/PID/status显示进程捕获的是哪个信号。但是,我想知道如何检查哪个处理程序正在处理信号。
例如:
void handler1(int sigNum)
{
if(sigNum == SIGINT)
printf("handler1 is handling SIGINT\n");
}
void handler2(int sigNum)
{
if(sigNum == SIGINT)
printf("handler2 is handling SIGINT\n");
}
void main()
{
signal(SIGINT, handler1);
signal(SIGINT, handler2);
while(1);
}
main函数注册了两个信号处理程序来处理SIGINT如何知道handler1或handler2已注册为处理SIGINT并正在处理SIGINT?
我想做同样的事情就像在Solaris下的psig一样。
What is the meaning of every column when executing psig command?
最佳答案
我尝试了一个监控程序,它使用动态帮助程序库执行插入了signal()
、sigaction()
和fork()
的目标进程。监视程序侦听传入的Unix域连接。
动态库非常简单。在启动时(使用Linux ELF二进制文件中支持的GCCconstructor
属性),它连接到监控程序。(成功fork()
后,新进程将关闭其描述符副本,并打开一个新连接。)在每次signal()
或sigaction()
调用时,它使用
struct change {
uint64_t addr;
char name[15];
unsigned char info; /* SA_RESETHAND; SIG_DFL/SIG_IGN */
};
库将信号号映射到名称(如
SIGINT
到"INT"
或SIGRTMIN+3
到"RTMIN+3"
)或未识别信号号的纯十进制数字字符串。这允许单个64位监视程序监视64位和32位进程的混合。info
字段用于报告SA_RESETHAND
(SA_ONESHOT
)信号处理程序,当信号传递到处理程序时,将重置为默认配置。它还用于指示SIG_DFL
和SIG_IGN
处理程序,以及可能的其他特殊事件。当建立新连接时,监控程序使用
readelf -W --syms --dyn-syms
或objdump -tT
或objdump -d
打开/proc/PID/exe
,记住二进制文件中每个已知函数的地址(或地址范围)。它记录每个连接的每个struct change
,以及一个时间戳。(建立连接时,插入库必须“暂停”,直到监视程序检查完二进制文件。否则,在监控程序有时间检查正确二进制之前,短运行二进制文件可能已经退出(或执行另一个二进制)。
在我的系统上,
bash
为地址447ad0安装SIGCHLD
处理程序,该地址没有关联的符号。例如,如果已知符号按升序排序,并且处理程序是相对于最近的符号指定的,则该处理程序可以报告为reap_dead_jobs+40 <447ad0>
。(注意reap_dead_jobs
位于[447a90,447ac1),因此查找覆盖地址的符号是不够的。)根据我的实验,把这看作是对应该有效的方法的描述。我自己的代码需要完全重写才能有用;这就是为什么我没有在这里包含它。我预计完成的项目大约有600-900行代码。
关于c - Linux:如何检查哪个处理程序正在处理信号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51644645/