4

によってインストールされたシグナル ハンドラvoid (*sa_sigaction)(int, siginfo_t *, void *);で、SIGILL が不正な命令から発生したのか、SIGILL を送信した何らかのプロセスから発生したのかをどのように判断できますか? si_pidsiginfo_tを見ましたが、不正な命令が発生した場合に備えて初期化されていないように見えるため、これに基づいて決定することはできません。-もちろん、命令コードを読んでsi_addrそれが合法かどうかを判断しようとするのではなく、できればシンプルでポータブルなソリューションを探しています。

4

1 に答える 1

8

正真正銘の SIGILL には、ILL_si_code値の 1 つ (たとえば、ILL_ILLADR) があります。ユーザーが要求した SIGILL にはsi_code、SI_ 値 (多くの場合 SI_USER) のいずれかが含まれます。

関連する POSIX 値は次のとおりです。

[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.

たとえば、この質問のレシピではILL_ILLOPN が得られますが、kill(1)とではkill(2)ゼロ (SI_USER) が得られます。

もちろん、実装によって POSIX リストに値が追加される場合があります。歴史的に、ユーザーまたはプロセスによって生成されsi_codeた値は <= 0であり、これは今でも非常に一般的です。実装には、ここでも役立つ便利なマクロが含まれている場合があります。たとえば、Linux は以下を提供します。

#define SI_FROMUSER(siptr)      ((siptr)->si_code <= 0)
#define SI_FROMKERNEL(siptr)    ((siptr)->si_code > 0)
于 2013-06-28T15:22:49.713 に答える