Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: restore stdio on program exit #20592

Closed
wants to merge 2 commits into from
Closed

src: restore stdio on program exit #20592

wants to merge 2 commits into from

Conversation

ktaborski
Copy link
Contributor

@ktaborski ktaborski commented May 8, 2018

Record the state of the stdio file descriptors on start-up and restore
them to that state on exit. This should prevent issues where node.js
sometimes leaves stdio in raw or non-blocking mode.

Author of change: @bnoordhuis

Continuation of #17737 as original pull request was closed.
Fixes: #14752

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added the c++ Issues and PRs that require attention from people who are familiar with C++. label May 8, 2018
@gireeshpunathil
Copy link
Member

@gireeshpunathil
Copy link
Member

looks really promising, let us see how the CI responds.

@gireeshpunathil
Copy link
Member

2 failures, one on freebsd:

07:35:12 not ok 2134 sequential/test-net-connect-local-error
07:35:12   ---
07:35:12   duration_ms: 0.234
07:35:12   severity: fail
07:35:12   exitcode: 1
07:35:12   stack: |-
07:35:12     assert.js:77
07:35:12       throw new AssertionError(obj);
07:35:12       ^
07:35:12     
07:35:12     AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
07:35:12     + expected - actual
07:35:12     
07:35:12     - undefined
07:35:12     + 12347
07:35:12         at Socket.onError (/usr/home/iojs/build/workspace/node-test-commit-freebsd/nodes/freebsd11-x64/test/sequential/test-net-connect-local-error.js:18:10)
07:35:12         at Socket.<anonymous> (/usr/home/iojs/build/workspace/node-test-commit-freebsd/nodes/freebsd11-x64/test/common/index.js:474:15)
07:35:12         at Socket.emit (events.js:182:13)
07:35:12         at emitErrorNT (internal/streams/destroy.js:82:8)
07:35:12         at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
07:35:12         at process._tickCallback (internal/process/next_tick.js:63:19)
07:35:12   ...

and one on arm:

not ok 309 parallel/test-crypto-dh-leak
  ---
  duration_ms: 1.558
  severity: fail
  exitcode: 1
  stack: |-
    assert.js:247
        throw err;
        ^
    
    AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
    
      assert(after - before < 5 << 20)
    
        at Object.<anonymous> (/home/iojs/build/workspace/node-test-commit-arm/nodes/ubuntu1604-arm64/test/parallel/test-crypto-dh-leak.js:26:1)
        at Module._compile (internal/modules/cjs/loader.js:678:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
        at Module.load (internal/modules/cjs/loader.js:589:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
        at Function.Module._load (internal/modules/cjs/loader.js:520:3)
        at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)
        at startup (internal/bootstrap/node.js:229:19)
        at bootstrapNodeJSCore (internal/bootstrap/node.js:577:3)

Does anyone know if this could be related to the PR?

@jasnell jasnell requested a review from bnoordhuis May 8, 2018 15:36
@Trott
Copy link
Member

Trott commented May 8, 2018

Is it possible/worthwhile to write at least a minimal test for this behavior?

@Trott
Copy link
Member

Trott commented May 8, 2018

@gireeshpunathil The first error has been seen in CI before: #18658

The second one is new to me.

Let's see what happens if we re-run CI:
https://ci.nodejs.org/job/node-test-pull-request/14719/

@gireeshpunathil
Copy link
Member

thanks @Trott - those 2 failures are vanished and new ones appear, so safe to assume these are unrelated flaky stuff.

@tabkrz - #18446 and #14752 have minimal test cases to reproduce the issue, please see if you can develop them into fully-blown tests.

A rough sketch would be:

  1. node -> non-node -> node
    After the granchild has exited, check for the fidelity of the non-node child
  2. The non-tty scenario that you have identified.

Please refer to test/parallel/test-child-process-spawn* test cases for general structure, spawn logic, validation logic etc.

@ktaborski
Copy link
Contributor Author

I will check.

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anyone know if this could be related to the PR?

My intuition would be “no”, but we should probably not land this PR without a fully green CI.

Next attempt: https://ci.nodejs.org/job/node-test-commit/18334/

@gireeshpunathil
Copy link
Member

interesting to see every time we run a new CI, the failure count increases, linearly!

btw what is ${STATUS_LABEL} — tests failed ? I don't remember seeing this earlier.

@Trott
Copy link
Member

Trott commented May 11, 2018

Just took some problematic CI nodes offline. Let's try again...

CI: https://ci.nodejs.org/job/node-test-commit/18400/

@gireeshpunathil
Copy link
Member

barring the unknown ${STATUS_LABEL} failure, the linux one is clearly infra:

13:54:49 make[1]: *** [Makefile:87: node] Terminated
13:54:49 make: *** [Makefile:465: build-ci] Terminated
13:54:49 FATAL: command execution failed
13:54:49 java.nio.channels.ClosedChannelException
13:54:49 	at org.jenkinsci.remoting.protocol.NetworkLayer.onRecvClosed(NetworkLayer.java:154)
13:54:49 	at org.jenkinsci.remoting.protocol.impl.NIONetworkLayer.ready(NIONetworkLayer.java:142)
13:54:49 	at org.jenkinsci.remoting.protocol.IOHub$OnReady.run(IOHub.java:789)
13:54:49 	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
13:54:49 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
13:54:49 	at 

@bnoordhuis
Copy link
Member

@tabkrz Can you keep my name on the code I wrote? I don't get too hung up on authorship if it's just a few lines but this is #17737 almost verbatim.

@ktaborski
Copy link
Contributor Author

@bnoordhuis, please check if current form of PR is sufficient to you.

Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tabkrz Yes, it's fine now. Left some comments on the second commit.

src/node.cc Outdated
@@ -3313,7 +3313,6 @@ void SetupProcessObject(Environment* env,


void SignalExit(int signo) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated whitespace change.

src/node.cc Outdated
@@ -4202,17 +4201,19 @@ inline void PlatformInit() {

s.flags = GetFileDescriptorFlags(fd);
CHECK_NE(s.flags, -1);

if (isatty(fd)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just if (isatty(fd)) continue; - saves a level of indent and makes the diff less noisy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, it should be if ( ! isatty(fd)) continue;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I mean, of course. :-)

src/node.cc Outdated
// tcgetattr() is not supposed to return ENODEV or EOPNOTSUPP
// but it does so anyway on MacOS.
CHECK(errno == ENODEV || errno == ENOTTY || errno == EOPNOTSUPP);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably be simplified to just this now:

s.isatty = true;
do {
  err = tcgetattr(fd, &s.termios);
} while (err == -1 && errno == EINTR);
CHECK_EQ(err, 0);

@gireeshpunathil
Copy link
Member

We never got a clean CI, at the same time the failures were inconclusive. So running once again:
CI: https://ci.nodejs.org/job/node-test-pull-request/14837/

@gireeshpunathil
Copy link
Member

all clean.

@gireeshpunathil gireeshpunathil added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label May 15, 2018
@BridgeAR
Copy link
Member

@bnoordhuis @tabkrz would it be fine for you to land this as a single commit that is done by @bnoordhuis and @tabkrz as a co-author?

@ktaborski
Copy link
Contributor Author

Fine for me.

@apapirovski
Copy link
Member

@tabkrz Could you update the commits to correctly have your github email and name associated with them? If we land these as is then you won't get proper credit for the work. Thanks!

(You can see our contributing guide for more info but basically it's this https://help.github.com/articles/setting-your-commit-email-address-in-git/)

@ktaborski
Copy link
Contributor Author

@apapirovski, done.

bnoordhuis and others added 2 commits May 22, 2018 11:43
Record the state of the stdio file descriptors on start-up and restore
them to that state on exit.  This should prevent issues where node.js
sometimes leaves stdio in raw or non-blocking mode.

Fixes: #14752
termios-flags can be stored only in TTY environment
@jasnell
Copy link
Member

jasnell commented May 23, 2018

@BridgeAR
Copy link
Member

I am unsure how to land this one. Without squashing the first commit is going to result in errors. Suggestions?

@MylesBorins MylesBorins mentioned this pull request Jun 6, 2018
stefwalter added a commit to stefwalter/cockpit that referenced this pull request Jun 23, 2018
Node leaves stdio file descriptors in non-blocking mode
when exiting. This has been reported, fixed, unfixed, ad nauseum.

nodejs/node#14752
nodejs/node#17737
nodejs/node#20592
nodejs/node#21257

Should this become a problem in more places, we could add such
a workaround elsewhere. But for now I'm limiting the ugliness to
the unit-tests container, where we see this cause a lot of failures.

Closes cockpit-project#9484
martinpitt pushed a commit to cockpit-project/cockpit that referenced this pull request Jun 24, 2018
Node leaves stdio file descriptors in non-blocking mode
when exiting. This has been reported, fixed, unfixed, ad nauseum.

nodejs/node#14752
nodejs/node#17737
nodejs/node#20592
nodejs/node#21257

Should this become a problem in more places, we could add such
a workaround elsewhere. But for now I'm limiting the ugliness to
the unit-tests container, where we see this cause a lot of failures.

Closes #9484
addaleax added a commit that referenced this pull request Jun 29, 2018
Before PR 20592, closing all handles associated with the main
event loop would also mean that `uv_tty_reset_mode()`
can’t function properly because the corresponding FDs have
already been closed.

Add regression tests for this condition.

Refs: #21020
Refs: #20592

PR-URL: #21027
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
martinpitt added a commit to cockpit-project/cockpituous that referenced this pull request Jul 12, 2018
Node leaves stdio file descriptors in non-blocking mode
when exiting. This has been reported, fixed, unfixed, ad nauseum.

nodejs/node#14752
nodejs/node#17737
nodejs/node#20592
nodejs/node#21257

Stolen from cockpit-project/cockpit@ef50d97cf4
rvagg pushed a commit that referenced this pull request Aug 16, 2018
Before PR 20592, closing all handles associated with the main
event loop would also mean that `uv_tty_reset_mode()`
can’t function properly because the corresponding FDs have
already been closed.

Add regression tests for this condition.

Refs: #21020
Refs: #20592

PR-URL: #21027
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
bnoordhuis added a commit to bnoordhuis/io.js that referenced this pull request May 24, 2019
Record the state of the stdio file descriptors on start-up and restore
them to that state on exit.  This should prevent issues where node.js
sometimes leaves stdio in raw or non-blocking mode.

This is a reworked version of commit c2c9c0c from May 2018 that was
reverted in commit 14dc17d from June 2018. The revert was a little
light on details but I infer that the problem was caused by a missing
call to `uv_tty_reset_mode()`.

Apropos the NOLINT comments: cpplint doesn't understand do/while
statements, it thinks they're while statements without a body.

Fixes: nodejs#14752
Fixes: nodejs#21020
Original-PR-URL: nodejs#20592
Trott pushed a commit to Trott/io.js that referenced this pull request Jun 13, 2019
Record the state of the stdio file descriptors on start-up and restore
them to that state on exit.  This should prevent issues where node.js
sometimes leaves stdio in raw or non-blocking mode.

This is a reworked version of commit c2c9c0c from May 2018 that was
reverted in commit 14dc17d from June 2018. The revert was a little
light on details but I infer that the problem was caused by a missing
call to `uv_tty_reset_mode()`.

Apropos the NOLINT comments: cpplint doesn't understand do/while
statements, it thinks they're while statements without a body.

Fixes: nodejs#14752
Fixes: nodejs#21020
Original-PR-URL: nodejs#20592

PR-URL: nodejs#24260
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann (רפאל פלחי) <refack@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
BridgeAR pushed a commit that referenced this pull request Jun 17, 2019
Record the state of the stdio file descriptors on start-up and restore
them to that state on exit.  This should prevent issues where node.js
sometimes leaves stdio in raw or non-blocking mode.

This is a reworked version of commit c2c9c0c from May 2018 that was
reverted in commit 14dc17d from June 2018. The revert was a little
light on details but I infer that the problem was caused by a missing
call to `uv_tty_reset_mode()`.

Apropos the NOLINT comments: cpplint doesn't understand do/while
statements, it thinks they're while statements without a body.

Fixes: #14752
Fixes: #21020
Original-PR-URL: #20592

PR-URL: #24260
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann (רפאל פלחי) <refack@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

nodejs sometimes leaves stdout/stderr in non-blocking mode