在通过 void (*sa_sigaction)(int, siginfo_t *, void *);
安装的信号处理程序中,我如何判断 SIGILL 是来自非法指令还是来自某个已发送的进程信号?我查看了 siginfo_t 的 si_pid
,但这似乎是未初始化的,以防遇到非法指令,所以我不能根据它做出决定。 - 当然,我正在寻找一个最好的简单且可移植的解决方案,而不是阅读 si_addr
处的指令代码并尝试确定它是否合法。
最佳答案
真正的 SIGILL 将具有 ILL_ 值之一的 si_code
(例如,ILL_ILLADR)。用户请求的 SIGILL 将具有一个 SI_ 值(通常是 SI_USER)的 si_code
。
[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)
关于linux - 我如何判断 SIGILL 是来自非法指令还是来自 kill -ILL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17367111/