2013-06-28 32 views
3

在通过void (*sa_sigaction)(int, siginfo_t *, void *);安装的信号处理程序中,如何判断SIGILL是源自非法指令还是发送SIGILL的某个进程?我查看了siginfo_t的si_pid,但是如果遇到非法指令,这似乎是未初始化的,所以我不能根据它做出决定。 - 当然,我正在寻找一种最简单便携的解决方案,而不是阅读si_addr的指令代码并试图确定它是否合法。如何判断SIGILL是源自非法指令还是kill -ILL?

+2

为什么要这么做? – ctn

+0

...为了找到一个Xenomai线程终止的原因,其中gdb表示“程序以信号4终止,非法指令”,但是在$ pc 核心文件中有合法的分支指令。 – Armali

回答

6

A 善意 SIGILL将具有其中一个ILL_值(例如,IL_ILLADR)的si_code。用户请求的SIGILL将具有其中一个SI_值(通常为SI_USER)的si_code

relevant POSIX values是:

[Kernel-generated] 
ILL_ILLOPC Illegal opcode. 
ILL_ILLOPN Illegal operand. 
ILL_ILLADR Illegal addressing mode. 
ILL_ILLTRP Illegal trap. 
ILL_PRVOPC Privileged opcode. 
ILL_PRVREG Privileged register. 
ILL_COPROC Coprocessor error. 
ILL_BADSTK Internal stack error. 

[User-requested] 
SI_USER  Signal sent by kill(). 
SI_QUEUE Signal sent by the sigqueue(). 
SI_TIMER Signal generated by expiration of a timer set by timer_settime(). 
SI_ASYNCIO Signal generated by completion of an asynchronous I/O request. 
SI_MESGQ Signal generated by arrival of a message on an empty message queue. 

例如,recipe in this question给我ILL_ILLOPN,而kill(1)kill(2)给我零(SI_USER)。

当然,您的实现可能会将值添加到POSIX列表中。历史上,user- or process-generated si_code values were <= 0,这仍然是相当普遍的。你的实现也可能有一个方便的宏来帮助你。例如,Linux提供:

#define SI_FROMUSER(siptr)  ((siptr)->si_code <= 0) 
#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) 
+0

实际上,'kill'生成的信号的'si_code'应该是'SI_USER',它通常是0,但在某些系统上可能是其他的东西。它将与所有ILL_值不同。 –

+0

@ChrisDodd,谢谢,更新。 – pilcrow

+0

@nos,是的,但是OP的测试显示他不能单靠这个领域。 – pilcrow

相关问题