linux - 我如何判断 SIGILL 是来自非法指令还是来自 kill -ILL?

标签 linux unix signals posix

在通过 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

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)

关于linux - 我如何判断 SIGILL 是来自非法指令还是来自 kill -ILL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17367111/

相关文章:

mysql - 自动将每 10 分钟生成的 Web 应用程序日志加载到 mysql

c - `c` 中的信号。 while循环的使用

c++ - 信号上的 QT 未定义引用编译错误

mysql - 错误 : 'Can' t connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)' -- Missing/var/run/mysqld/mysqld. socks

c++ - 如何在 Qt 的 Linux 上获取 USB 驱动器的路径?

python - 从 python 调用进程的最快方法?

使用 shell 脚本的 Java 代码格式化

c - Unix 表示奇怪的行为。 ( child 多次退出)

shell - KornShell - 使用可能未设置的变量进行测试

c++ - Qt信号/插槽问题