在通过void(* sa_sigaction)(int,siginfo_t *,void *);安装的信号处理程序中,如何判断SIGILL是来自非法指令还是来自已发送SIGILL的某个进程?我查看了siginfo_t的si_pid,但是如果遇到非法指令,这似乎是未初始化的,所以我不能根据它做出决定. – 当然,我正在寻找一个最好的简单易用的解决方案,而不是在si_addr上读取指令代码并试图确定它是否合法.
解决方法:
真正的SIGILL将具有ILL_值之一(例如,IL_ILLADR)的si_code.用户请求的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,posix,unix,signals
来源: https://codeday.me/bug/20190823/1695940.html