cpan-authors / IPC-Run

https://metacpan.org/pod/IPC::Run
Other
21 stars 38 forks source link

Contents of stdout/stderr may be lost in case of EINTR on read() #176

Closed alexanderlaw closed 1 month ago

alexanderlaw commented 1 month ago

The run() routine may silently return an empty stdout/stderr string instead of actual pipe data if POSIX::read() inside _read() failed with EINTR.

This behaviour was first observed during PostgreSQL testing on a macOS machine (1): https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=indri&dt=2024-10-02%2002%3A34%3A16

[22:38:14.887](0.014s) ok 362 - pgbench script error: sleep undefined variable status (got 2 vs expected 2)
[22:38:14.887](0.000s) ok 363 - pgbench script error: sleep undefined variable stdout /(?^:processed: 0/1)/
[22:38:14.887](0.000s) not ok 364 - pgbench script error: sleep undefined variable stderr /(?^:sleep: undefined variable)/
[22:38:14.887](0.000s) 
[22:38:14.887](0.000s) #   Failed test 'pgbench script error: sleep undefined variable stderr /(?^:sleep: undefined variable)/'
#   at t/001_pgbench_with_server.pl line 1242.
[22:38:14.887](0.000s) #                   ''
#     doesn't match '(?^:sleep: undefined variable)'

(1) Darwin Kernel Version 24.0.0: Mon Aug 12 20:49:48 PDT 2024; root:xnu-11215.1.10~2/RELEASE_ARM64_T8103, perl 5.34.3.

Reproduced on another macOS machine (2) with the attached TAP test: read_eintr.tar.gz

when running the test in parallel (I could not reproduce the issue with -j1, -j2): parallel --halt now,fail=1 -j10 --linebuffer --tag make test TEST_FILES="t/read_eintr.t" N={} ::: {1..10}

7       t/read_eintr.t .. 
7       Dubious, test returned 1 (wstat 256, 0x100)
7       Failed 1/1 subtests 
7
7       Test Summary Report
7       -------------------
7       t/read_eintr.t (Wstat: 256 Tests: 1 Failed: 1)
7         Failed test:  1
7         Non-zero exit status: 1
7       Files=1, Tests=1,  4 wallclock secs ( 0.01 usr  0.00 sys +  1.79 cusr  1.18 csys =  2.98 CPU)
7       Result: FAIL
7       # stderr: "" on iteration 316.

(2) Darwin Kernel Version 23.5.0: Wed May 1 20:16:51 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T8103, perl 5.34.3.

Not reproduced on Fedora 40, FreeBSD 13, Ubuntu 22.04.

To trigger the issue, a child process should perform something like this (cf. pg_log_error()):

print STDERR 'string 1';
delay;
print STDERR 'string 2';
exit;

A fix proposed at https://www.postgresql.org/message-id/20241004185748.22.nmisch%40google.com (_read.tar.gz) makes the read_eintr test pass reliably (10 runs with -j40 succeeded for me).