Closed masnagam closed 4 years ago
In the provided example, the child process (cat
) is spawned with its stdin and stdout redirected from/to the parent. When the input is written, cat
will immediately block while trying to write to it's stdout, since the parent never tries to read from that pipe.
Although the child.kill()
is succeeding, I'm not sure why the kernel doesn't appear to kill the process. On macOS I get a broken pipe error from cat
and the program will exit (maybe on linux the kill waits until the write to stdout terminates?)
Can you try setting .stdout(Stdio::null())
and see if the problem still occurs? If it does, can you check if the state of the cat
process and see if it is a zombie process or still considered active?
I confirmed in the Docker container case that cat
is killed by child.kill()
, using ps aux | grep cat
.
Can you try setting .stdout(Stdio::null()) and see if the problem still occurs?
Yes, sure.
Maybe, it's difficult.. Because if we set .stdout(Stdio::null())
, the input data is consumed quickly and it's not easy to block in input.write_all(&data).await
. But, anyway, I'll try that.
We can reproduce the same issue with null stdout. However, the reproduction rate is not 100%, maybe, due to the reason as I wrote the previous comment.
I confirmed that the cat
process doesn't exist by using ps aux | grep cat
in the Docker container.
Updated the test program in order to check the task states: https://github.com/masnagam/rust-case-studies/commit/294849f5243e8a0b6c1956a8b288b64fba7afe23
When the issue occurs, the task is blocked at input.write_all(&data).await
:
Waiting for the task...: writing(true) shutdown(false)
When the task ends due to a broken pipe error:
Input error: Broken pipe (os error 32)
Waiting for the task...: writing(false) shutdown(false)
Done
In this case SIGCHLD
occurs.
There might be some issues regarding signal handlings in tokio.
The SIGCHLD
for the child process cat
is handled in Reaper::poll()
. However, the SIGCHLD
seems not to handle in ChildStdin
and the Reaper
seems not to notify the SIGCHLD
of ChildStdin
.
Is my understanding correct?
If correct, I think that it's necessary to wake up the pending write_all()
task in some way.
Thanks for the detailed notes, I can confirm that I'm also able to successfully reproduce this on linux myself.
It appears that the root of the issue is that a task waiting to write to the child's stdin is not being woken up if the pipe reader goes away, even though the child process is being successfully killed and reaped.
As far as I can tell, the PollEvented
wrapper around the child's stdin handle is correctly registering for hup
interest (aka the other end of the pipe hung up and we should wake to then run into an error or complete). My theory as to what could be going wrong:
PollEvented
and mio
with either registering, receiving, or dispatching readiness/hup events. The evidence for this would be the fact that on macOS/kqueue the program immediately halts with an error, while on linux/epoll the hang occursI slightly tweaked the program as follows:
#[tokio::main]
to #[tokio::main(core_threads = 1)]
for easier debugging with a single threaded runtimecat
to sh -c 'exec 0<&-;'
to more easily simulate closing the child's stdin reader side and immediately exitingkill
callI ran the program via strace
, the output is below (pasting it here so people can take a look, I can come back later and annotate the report with what I can see happening given my understanding of the tokio internals)
execve("./target/debug/tokio-process-stdio-hup", ["./target/debug/tokio-process-std"...], 0x7fff0a8e0838 /* 21 vars */) = 0 brk(NULL) = 0x561cd1408000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=28038, ...}) = 0 mmap(NULL, 28038, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8af0e18000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\16\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=14560, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8af0e16000 mmap(NULL, 2109712, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af09f4000 mprotect(0x7f8af09f7000, 2093056, PROT_NONE) = 0 mmap(0x7f8af0bf6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f8af0bf6000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\"\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=31680, ...}) = 0 mmap(NULL, 2128864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af07ec000 mprotect(0x7f8af07f3000, 2093056, PROT_NONE) = 0 mmap(0x7f8af09f2000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f8af09f2000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000b\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=144976, ...}) = 0 mmap(NULL, 2221184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af05cd000 mprotect(0x7f8af05e7000, 2093056, PROT_NONE) = 0 mmap(0x7f8af07e6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19000) = 0x7f8af07e6000 mmap(0x7f8af07e8000, 13440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8af07e8000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300*\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=96616, ...}) = 0 mmap(NULL, 2192432, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8af03b5000 mprotect(0x7f8af03cc000, 2093056, PROT_NONE) = 0 mmap(0x7f8af05cb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x7f8af05cb000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0 mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8aeffc4000 mprotect(0x7f8af01ab000, 2097152, PROT_NONE) = 0 mmap(0x7f8af03ab000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f8af03ab000 mmap(0x7f8af03b1000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8af03b1000 close(3) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8af0e14000 arch_prctl(ARCH_SET_FS, 0x7f8af0e15400) = 0 mprotect(0x7f8af03ab000, 16384, PROT_READ) = 0 mprotect(0x7f8af05cb000, 4096, PROT_READ) = 0 mprotect(0x7f8af07e6000, 4096, PROT_READ) = 0 mprotect(0x7f8af09f2000, 4096, PROT_READ) = 0 mprotect(0x7f8af0bf6000, 4096, PROT_READ) = 0 mprotect(0x561cd064d000, 69632, PROT_READ) = 0 mprotect(0x7f8af0e1f000, 4096, PROT_READ) = 0 munmap(0x7f8af0e18000, 28038) = 0 set_tid_address(0x7f8af0e156d0) = 3543 set_robust_list(0x7f8af0e156e0, 24) = 0 rt_sigaction(SIGRTMIN, {sa_handler=0x7f8af05d2cb0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8af05df890}, NULL, 8) = 0 rt_sigaction(SIGRT_1, {sa_handler=0x7f8af05d2d50, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f8af05df890}, NULL, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f8af0002f20}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 brk(NULL) = 0x561cd1408000 brk(0x561cd1429000) = 0x561cd1429000 openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 read(3, "561cd0262000-561cd044e000 r-xp 0"..., 1024) = 1024 read(3, "f8af03b5000 rw-p 00000000 00:00 "..., 1024) = 1024 read(3, "73 /lib/x8"..., 1024) = 1024 read(3, " 2068 /lib"..., 1024) = 541 close(3) = 0 sched_getaffinity(3543, 32, [0, 1]) = 8 rt_sigaction(SIGSEGV, {sa_handler=0x561cd03c95d0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f8af05df890}, NULL, 8) = 0 rt_sigaction(SIGBUS, {sa_handler=0x561cd03c95d0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f8af05df890}, NULL, 8) = 0 sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8af0e1d000 sigaltstack({ss_sp=0x7f8af0e1d000, ss_flags=0, ss_size=8192}, NULL) = 0 openat(AT_FDCWD, "/proc/cpuinfo", O_RDONLY|O_CLOEXEC) = 3 fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC) getrandom("\x42\xfc\xb4\x6f\xd1\xc1\x49\xbd\x8e\x99\x9f\xe9\xb6\xf5\xe0\xf2", 16, GRND_NONBLOCK) = 16 read(3, "processor\t: 0\nvendor_id\t: Genuin"..., 8192) = 1714 read(3, "", 8192) = 0 close(3) = 0 futex(0x7f8af0bf70c8, FUTEX_WAKE_PRIVATE, 2147483647) = 0 epoll_create1(EPOLL_CLOEXEC) = 3 pipe2([4, 5], O_NONBLOCK|O_CLOEXEC) = 0 epoll_ctl(3, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLET, {u32=4294967295, u64=18446744073709551615}}) = 0 pipe2([6, 7], O_CLOEXEC) = 0 openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CLOEXEC) = 8 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0 mmap(NULL, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f8af0e0b000 rt_sigprocmask(SIG_BLOCK, ~[], [], 8) = 0 clone(strace: Process 3544 attached[pid 3544] rt_sigprocmask(SIG_BLOCK, NULL, ~[KILL STOP], 8) = 0 [pid 3544] rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGHUP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGINT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGQUIT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGILL, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGILL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGTRAP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGTRAP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGABRT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGABRT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGBUS, NULL, {sa_handler=0x561cd03c95d0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f8af05df890}, 8) = 0 [pid 3544] rt_sigaction(SIGBUS, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGFPE, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGFPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGUSR1, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGUSR1, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGSEGV, NULL, {sa_handler=0x561cd03c95d0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f8af05df890}, 8) = 0 [pid 3544] rt_sigaction(SIGSEGV, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGUSR2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGUSR2, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGALRM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGALRM, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGTERM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGTERM, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGSTKFLT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGSTKFLT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGCHLD, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGCONT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGCONT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGTSTP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGTTIN, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGTTOU, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGURG, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGURG, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGXCPU, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGXCPU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGXFSZ, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGXFSZ, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGVTALRM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGVTALRM, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGPROF, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGPROF, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGWINCH, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGWINCH, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGIO, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGIO, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGPWR, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGPWR, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGSYS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGSYS, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRTMIN, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_1, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_2, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_3, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_3, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_4, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_4, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_5, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_5, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_6, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_6, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_7, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_7, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_8, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_8, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_9, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_9, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_10, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_10, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_11, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_11, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_12, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_12, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_13, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_13, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_14, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_14, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_15, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_15, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_16, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_16, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_17, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_17, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_18, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_18, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_19, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_19, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_20, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_20, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_21, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_21, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_22, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_22, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_23, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_23, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_24, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_24, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_25, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_25, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_26, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_26, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_27, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_27, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_28, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_28, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_29, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_29, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_30, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_30, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_31, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_31, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGRT_32, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGRT_32, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f8af0002f20}, NULL, 8) = 0 [pid 3544] dup2(6, 0) = 0 [pid 3544] dup2(8, 1) = 1 [pid 3544] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 3544] execve("/home/vagrant/.cargo/bin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */) = -1 ENOENT (No such file or directory) [pid 3544] execve("/usr/local/sbin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */) = -1 ENOENT (No such file or directory) [pid 3544] execve("/usr/local/bin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */) = -1 ENOENT (No such file or directory) [pid 3544] execve("/usr/sbin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */) = -1 ENOENT (No such file or directory) [pid 3544] execve("/usr/bin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */) = -1 ENOENT (No such file or directory) [pid 3544] execve("/sbin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */) = -1 ENOENT (No such file or directory) [pid 3544] execve("/bin/sh", ["sh", "-c", "exec 0<&-;"], 0x7ffca7d426c8 /* 21 vars */ [pid 3543] <... clone resumed> child_stack=0x7f8af0e13ff0, flags=CLONE_VM|CLONE_VFORK|SIGCHLD) = 3544 [pid 3543] munmap(0x7f8af0e0b000, 36864) = 0 [pid 3543] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 3543] close(6) = 0 [pid 3543] close(8) = 0 [pid 3543] fcntl(7, F_GETFL) = 0x1 (flags O_WRONLY) [pid 3543] fcntl(7, F_SETFL, O_WRONLY|O_NONBLOCK) = 0 [pid 3543] epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLPRI|EPOLLOUT|EPOLLET, {u32=0, u64=0}}) = 0 [pid 3543] socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, [6, 8]) = 0 [pid 3543] rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 [pid 3543] rt_sigaction(SIGCHLD, {sa_handler=0x561cd037bbc0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO|SA_NOCLDSTOP, sa_restorer=0x7f8af05df890}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3543] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 3543] fcntl(6, F_DUPFD_CLOEXEC, 0) = 9 [pid 3543] fcntl(9, F_GETFD) = 0x1 (flags FD_CLOEXEC) [pid 3543] epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLPRI|EPOLLOUT|EPOLLET, {u32=1, u64=1}}) = 0 [pid 3543] wait4(3544, 0x7ffca7d3c5e8, WNOHANG, NULL) = 0 [pid 3543] epoll_wait(3, [{EPOLLOUT, {u32=0, u64=0}}, {EPOLLOUT, {u32=1, u64=1}}], 1024, -1) = 2 [pid 3543] wait4(3544, 0x7ffca7d3c5e8, WNOHANG, NULL) = 0 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192 [pid 3543] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = -1 EAGAIN (Resource temporarily unavailable) [pid 3543] epoll_wait(3, [pid 3544] <... execve resumed> ) = 0 [pid 3544] brk(NULL) = 0x55a90874b000 [pid 3544] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) [pid 3544] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) [pid 3544] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 [pid 3544] fstat(3, {st_mode=S_IFREG|0644, st_size=28038, ...}) = 0 [pid 3544] mmap(NULL, 28038, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f355eb9c000 [pid 3544] close(3) = 0 [pid 3544] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) [pid 3544] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 [pid 3544] read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832 [pid 3544] fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0 [pid 3544] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f355eb9a000 [pid 3544] mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f355e58b000 [pid 3544] mprotect(0x7f355e772000, 2097152, PROT_NONE) = 0 [pid 3544] mmap(0x7f355e972000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f355e972000 [pid 3544] mmap(0x7f355e978000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f355e978000 [pid 3544] close(3) = 0 [pid 3544] arch_prctl(ARCH_SET_FS, 0x7f355eb9b540) = 0 [pid 3544] mprotect(0x7f355e972000, 16384, PROT_READ) = 0 [pid 3544] mprotect(0x55a907aad000, 8192, PROT_READ) = 0 [pid 3544] mprotect(0x7f355eba3000, 4096, PROT_READ) = 0 [pid 3544] munmap(0x7f355eb9c000, 28038) = 0 [pid 3544] getuid() = 1000 [pid 3544] getgid() = 1000 [pid 3544] getpid() = 3544 [pid 3544] rt_sigaction(SIGCHLD, {sa_handler=0x55a9078a4200, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER, sa_restorer=0x7f355e5c9f20}, NULL, 8) = 0 [pid 3544] geteuid() = 1000 [pid 3544] brk(NULL) = 0x55a90874b000 [pid 3544] brk(0x55a90876c000) = 0x55a90876c000 [pid 3544] getppid() = 3543 [pid 3544] stat("/home/vagrant/rust-case-studies/tokio-process-stdio-hup", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 [pid 3544] stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 [pid 3544] geteuid() = 1000 [pid 3544] getegid() = 1000 [pid 3544] rt_sigaction(SIGINT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGINT, {sa_handler=0x55a9078a4200, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER, sa_restorer=0x7f355e5c9f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGQUIT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER, sa_restorer=0x7f355e5c9f20}, NULL, 8) = 0 [pid 3544] rt_sigaction(SIGTERM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 [pid 3544] rt_sigaction(SIGTERM, {sa_handler=SIG_DFL, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER, sa_restorer=0x7f355e5c9f20}, NULL, 8) = 0 [pid 3544] fcntl(0, F_DUPFD, 10) = 10 [pid 3544] close(0) = 0 [pid 3544] fcntl(10, F_SETFD, FD_CLOEXEC) = 0 [pid 3544] close(10 [pid 3543] <... epoll_wait resumed> [{EPOLLERR, {u32=0, u64=0}}], 1024, -1) = 1 [pid 3543] wait4(3544, 0x7ffca7d3c5e8, WNOHANG, NULL) = 0 [pid 3543] epoll_wait(3, [pid 3544] <... close resumed> ) = 0 [pid 3544] exit_group(0) = ? [pid 3544] +++ exited with 0 +++ <... epoll_wait resumed> 0x561cd140ade0, 1024, -1) = -1 EINTR (Interrupted system call) --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=3544, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- write(8, "\1", 1) = 1 rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call) epoll_wait(3, [{EPOLLIN|EPOLLOUT, {u32=1, u64=1}}], 1024, -1) = 1 recvfrom(9, "\1", 128, 0, NULL, NULL) = 1 recvfrom(9, 0x7ffca7d3c4b0, 128, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) wait4(3544, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 3544 epoll_ctl(3, EPOLL_CTL_DEL, 9, 0x7ffca7d3c550) = 0 close(9) = 0 write(1, "Waiting for the task...: writing"..., 55Waiting for the task...: writing(true) shutdown(false) ) = 55 epoll_wait(3, [], 1024, 0) = 0 epoll_wait(3, [], 1024, 0) = 0 epoll_wait(3, ^Cstrace: Process 3543 detached
Thank you for your comments and investigation.
I updated the test program according to your comments. I also added workaround patches, but these are NOT perfect solutions.
I'm not familiar with syscalls, but it seems that no EPOLLHUP
was specified in epoll_ctl()
:
pipe2([6, 7], O_CLOEXEC) = 0
...
[pid 3544] dup2(6, 0) = 0
...
[pid 3543] epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLPRI|EPOLLOUT|EPOLLET, {u32=0, u64=0}}) = 0
I updated the test program according to your comments. I also added workaround patches, but these are NOT perfect solutions.
Yes I agree completely, something is definitely amiss here. I've asked @kleimkuhler to take a look when he's got a chance since he's more familiar with the reactor/mio internals than I am :)
Thank you for your reply.
UnixReady::hup()
passed in tokio::process::unix
is never used in mio
like blow:
https://github.com/tokio-rs/mio/blob/v0.6.20/src/sys/unix/epoll.rs#L133
According to the description below, epoll_wait()
always waits for EPOLLHUP
:
http://man7.org/linux/man-pages/man7/epoll.7.html
That might be the reason why mio
doesn't check UnixReady::hup()
.
In the master branch of mio
, EPOLLRDHUP
is used if a specified fd is readable. However, no special flags are added for a writable fd. I haven't confirmed, but a similar issue might occur in the latest mio
.
According to the description below, epoll_wait() always waits for EPOLLHUP
Hi @masnagam. That is correct. EPOLLHUP
does not need to be explicitly set in the events passed in to the epoll instance. However, EPOLLRDHUP
does need to be explicitly listed as an event of interest in order to get wake ups when that event occurs.
EPOLLRDHUP
occurs when socket has shutdown it's read half. It also occurs when a socket has observed the FIN packet sent by it's peer shutting down it's read half.
I've spent some time looking into the issue above and I have not (so far) produced something that is 100% reliable by registering interest in additional events. Even when the spawned task registers interest in EPOLLRDHUP
and tries to write to when that occurs, I'm not seeing that event always occur.
What I'm still looking into is what sort of shutdown process the child process goes through when it closes. If it closes without properly calling shutdown(fd, SHUT_RD) / shutdown(fd, SHUT_RDWR)
, then there is nothing for the spawned task to acknowledge and no events would occur.
I'll update this issue as I continue looking into it. I have the availability to continue looking into it this evening/tomorrow.
Thank you for your explanation, @kleimkuhler.
I updated tokio in my test program. This issue still occurs in tokio v0.2.11 (w/ mio v0.6.21).
Please let me know if there is anything I can help you.
@kleimkuhler I slightly improved execution time by replacing tokio::time::delay_for()
with rx.await
.
https://github.com/masnagam/rust-case-studies/commit/02e5d589fe0773f07451f1d791333b8ca5ec3177
This change improves test execution time.
@masnagam I believe #2218 should fix this issue once it lands
@ipetkov @kleimkuhler Thank you for your efforts!
Unit test execution time may be improved by applying https://github.com/masnagam/rust-case-studies/commit/02e5d589fe0773f07451f1d791333b8ca5ec3177 which removes tokio::time::delay_for()
and notifies of pending in write_all()
by using oneshot::channel()
.
Version
Platform
Docker rust:1.40.0
Subcrates
Description
In the following situation,
poll_write()
ontokio::process::ChildStdin
will never called when killing the child process.I expected that the task ends with a broken pipe error, but it never ends actually. This issue doesn't occur on macOS. I haven't checked on Windows.
I prepared a reproduction environment for Linux. Try the following code on Linux or VS Code Remote Container:
It seems that there is some issue in tokio-process, tokio-io or mio.