Repository navigation
stdio regression: process.stdin getter drops pending stdin data #36251
Description
Activity
able to recreate with the said version, but not consistently.
- If I run ~10 times, ~2 runs go fine.
- If I run it under dtruss, it passes consistently
so I believe there is a race condition happening here.
@gireeshpunathil Yes there is. The
ReadingStreamstarts reading immediately as well as theclone/execpath. This is the race condition. If libuv was able to read from the fd before theclone/exec, that the data is lost.
On Linux, at least on my machine,straceallows you to observe both situations.
@joyeecheung maybe create theReadStreamin stopped state?Reacted by Gireesh Punathil@mmomtchev - thanks, I too got a linux box which recreates pretty easily.
passing case:
[pid 661072] execve("/bin/bash", ["/bin/bash"], 0x55dd87501770 /* 22 vars */ <unfinished ...> ... [pid 661072] read(0, "#!/bin/bash\necho \"hello from nod"..., 49) = 49 [pid 661072] fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0 [pid 661072] write(1, "hello from node's child shell\n", 30) = 30 [pid 661072] read(0, "", 49) = 0 [pid 661072] rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 [pid 661072] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 661072] exit_group(0) = ?
the process
661072is exec'ing intobashand reads from 0.failing case:
489 [pid 661087] execve("/bin/bash", ["/bin/bash"], 0x557edd43a770 /* 22 vars */ <unfinished ...> ... 615 [pid 661088] <... read resumed>"#!/bin/bash\necho \"hello from nod"..., 65536) = 49 .. 701 [pid 661087] read(0, "", 49) = 0 702 [pid 661087] rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 703 [pid 661087] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 704 [pid 661087] exit_group(0) = ?
The process
661087is exec'ing intobashbut does ot get any data, due to the previous read by661088- but what it is? (it is cloned from661080which is the parent process)@gireeshpunathil @isaacs I solved it by implementing a
manualStartforReadStreamthen using it in theprocess.stdingetter, just a sec to clean my debug printfs and if the unit tests pass, I will submit the PR@gireeshpunathil All other stdio
ReadStreamstart in paused mode - except file - which didn't have amanualStartoptionReacted by Gireesh Punathil@isaacs @gireeshpunathil This will be a platform-dependent unit test, exclusive to
darwinandlinuxunless you have an idea?- added a commit that references this issue
on Nov 26, 2020 The unit test is awful, I admit, if you have any ideas, fell free to comment
- addedprocessIssues and PRs related to the process subsystem.Issues and PRs related to the process subsystem.
on Dec 16, 2020 - added a commit that references this issue
on Jan 5, 2021 - added a commit that references this issue
on Jan 12, 2021 - added a commit that references this issue
on May 22, 2026
What steps will reproduce the bug?
In v15, if
process.stdinis referenced, and is not a TTY or Pipe, then its data will be not be seen when passed to a child process. It's almost like it's already consumed or something.How often does it reproduce? Is there a required condition?
100% of the time on node 15. Not in any prior version tested (14, 12, and 10).
What is the expected behavior?
Stdin data should not be consumed when
process.stdinis merely referenced. This causes problems when a script checksprocess.stdin.isTTYto print a helpful message prior to opening a shell in a child process.What do you see instead?
Stdin data is not passed to child process if stdin is referenced, and not a Pipe or TTY.
Additional information
This kind of is a pain for
npm exec. It means you can't do something likenpx some-interactive-thing < list-of-commands.