Why don't lio_listio's signals get delivered?
Konstantin Belousov
kostikbel at gmail.com
Mon Nov 30 09:44:27 UTC 2020
On Sun, Nov 29, 2020 at 05:54:32PM -0700, Alan Somers wrote:
> I'm investigating https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=220398
> . What happens is that lio_listio sends a signal to the current process
> (synchronously, from within the lio_listio syscall itself, not after some
> I/O completes). With dtrace, I've verified that the signal isn't masked,
> that it is caught, and that signotify and tdsigwakeup do get called. But
> after lio_listio returns, the process never receives the signal. If it
> registers a handler, the handler never gets called. If I set the signal to
> SIGTERM, the process doesn't get terminated. It's as if the signal is
> ignored. Asynchronously generated signals still work, however.
>
> What's going on? My knowledge of signal-delivery internals is running out,
> and I would appreciate some help.
>
> Steps to reproduce:
> $ cd /usr/tests/sys/aio
> $ kyua debug lio_test:lio_listio_empty_nowait_signal
>
> Stack trace at the time the signal looks like it's being delivered:
> kernel`tdsendsignal+0x4e1
> kernel`kern_lio_listio+0x493
> kernel`sys_lio_listio+0xc2
> kernel`amd64_syscall+0x12e
> kernel`0xffffffff81007e1e
>
> lio_listio is attempting to send this signal via aio_sendsig, 24 lines from
> the bottom of kern_lio_listio.
Yes, the signal is queued to the current process, but then, several lines
below it, it is dequeued. Look at the block with if (lj->lioj_count == 0)
right above the finalization of error code.
Problem is that ksi is embedded into aioliojob, and the later needs to be
freed there when nitems == 0, because there is no callback. Perhaps, if
you need signal to be delivered, we need to allocate ksi just in this case.
BTW, I think there is a similar problem with knote, it is not delivered
to userspace because knote is signalled but then deleted from kq before
syscall returns.
More information about the freebsd-hackers
mailing list