Open3

WasmLinux: 同期シグナルに対応する

okuokuokuoku

... といっても SIGSEGV とか SIGBUS は発生しない(nommuなので)。メモリの下位64kはunmapしておくとかでエラーにした方が良いかもしれんな。。

要するに、 sigaction でシグナルハンドラを設定 → raise(3) で SIGUSR1 あたりのシグナルを送信 → シグナルハンドラが呼ばれる の一連の動作を実装する。

okuokuokuoku

struct ksignal の中身を調べる

スレッドに配送されたシグナルを受けとると、 struct ksignal が受けとれる。

https://github.com/lkl/linux/blob/970883c348b61954a11c8c1ab9a2ab3ff0d89f08/include/linux/signal_types.h#L67-L71

https://github.com/lkl/linux/blob/970883c348b61954a11c8c1ab9a2ab3ff0d89f08/include/linux/signal_types.h#L51-L56

https://github.com/lkl/linux/blob/970883c348b61954a11c8c1ab9a2ab3ff0d89f08/include/linux/signal_types.h#L37-L49

https://github.com/lkl/linux/blob/970883c348b61954a11c8c1ab9a2ab3ff0d89f08/include/linux/signal_types.h#L12-L14

https://github.com/lkl/linux/blob/970883c348b61954a11c8c1ab9a2ab3ff0d89f08/include/uapi/asm-generic/siginfo.h#L122-L128

まぁ要するに sigaction と siginfo の順で並んでるわけだな。(ユーザランド版のsiginfoはpadされている)

実際に先頭をダンプしてみると:

[    0.189118] get_signal: signal 10 sizeof(ksignal) = 52 sizeof(sigaction) = 16 sizeof(siginfo) = 32
// 52 / 4 = 13 ワード(全体)
// 16 / 4 = 4 ワード(sigaction)
// 32 / 8 = 8 ワード(siginfo)

// sigaction
[000]: 0x00000003 3 // ★ sa_handlerハンドラのWasm関数ポインタ
[001]: 0x00000004 4 // ★ sa_flags = SA_SIGINFO -- 3引数版のハンドラを起動
[002]: 0x00000006 6
[003]: 0x00000000 0

// siginfo
[004]: 0x0000000a 10 // ★ si_signo = 受信したシグナル = SIGUSR1
[005]: 0x00000000 0  // ★ si_errno
[006]: 0xfffffffa -6 // ★ si_code ???
[007]: 0x0000001b 27
[008]: 0x00000000 0
[009]: 0x00000000 0
[010]: 0x00000000 0
[011]: 0x00000000 0

// sig
[012]: 0x0000000a 10 // ★ sig = 受信したシグナル = SIGUSR1

というわけで今回は3番の関数を引数 (10, siginfoの先頭アドレス, NULL) で呼べば良いと見られる。最後の引数は ucontext_t だがWebAssemblyではucontextもクソも無いため一旦NULLにしてみる。将来WebAssembly的なtrapを SIGSEGV なり何なりに割り当てるときは、siginfoの方を使うべきだと思う。