linux-user: fails to deliver signals raised during pselect
Host environment
- Operating system: NixOS
- OS/kernel version: Linux nix-build 5.10.92 #1-NixOS SMP Sun Jan 16 08:14:24 UTC 2022 x86_64 GNU/Linux
- Architecture: x86_64
- QEMU flavor: linux-user
- QEMU version: qemu-x86_64 version 6.2.50 (v6.2.0-1117-gaeb0ae95)
Description of problem
When run via qemu a program which blocks signals but unmasks them during pselect
does not catch these signals when returning from pselect
.
Used as reference on expected behavior: The new pselect() system call
Steps to reproduce
A minimal test case below mimics behavior as encountered in the test suite of p11-kit
(link) (which attempts to catch SIGTERM
in a similar way and results in lingering processes after running the test suite).
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/select.h>
static void handler(int sig)
{
puts("SIGNAL");
}
int main(int argc, char *argv[])
{
struct sigaction sa;
fd_set rfds;
sigset_t emptyset, blockset;
sigemptyset (&blockset);
sigemptyset (&emptyset);
sigaddset (&blockset, SIGUSR1);
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGUSR1, &sa, NULL);
sigprocmask (SIG_BLOCK, &blockset, NULL);
FD_ZERO(&rfds);
while(1) {
pselect(0, &rfds, NULL, NULL, NULL, &emptyset);
}
return 0;
}
Running this without qemu should print SIGNAL when sent SIGUSR1
:
$ ./a.out &
[1] 1683587
$ kill -USR1 %1
$ SIGNAL
When run with qemu-x86_64
however, it does not (also qemu's -strace
confirms the signal isn't received whereas a strace of qemu shows it's in fact delivered).
The pselect call itself is interrupted, but the signal goes missing.