Repository: node
Issue: vm: timeout raised by vm.runInContext breaks console.log
Labels: vm,console,stdio

<!--
Thank you for reporting an issue.

This issue tracker is for bugs and issues found within Node.js core.
If you require more general support please file an issue on our help
repo. https://github.com/nodejs/help


Please fill in as much of the template below as you're able.

Version: output of `node -v`
Platform: output of `uname -a` (UNIX), or version and 32 or 64-bit (Windows)
Subsystem: if known, please specify affected core module name
-->

* **Version**: v10.22.0
* **Platform**: Linux raspberrypi 4.19.118-v7+ #1311 SMP Mon Apr 27 14:21:24 BST 2020 armv7l GNU/Linux
* **Subsystem**: vm module

### What steps will reproduce the bug?

<!--
Enter details about your bug, preferably a simple code snippet that can be
run using `node` directly without installing third-party dependencies.
-->
I have created the following snippet to reproduce the problem:
```
const vm = require('vm');

let context = vm.createContext({ process: process });

let countErr = 0;
while (process.stdout._writableState.bufferedRequestCount == 0 && countErr < 10) {
    try {
        vm.runInContext("while (true) {process.stdout.write('');}",
            context,
            { timeout: 100 });
    } catch (err) {
        countErr++;
        console.warn(err.message);
    }
}
console.error("stdout bufferedRequestCount:", process.stdout._writableState.bufferedRequestCount);
console.error('Needed to raise that many timeouts to show the problem:', countErr);
console.log('Log in main still working'); // after some timeouts, this line does not print anymore
console.error("The previous line should be 'Log in main still working', if it is not, stdout seems to be broken...");
````

### How often does it reproduce? Is there a required condition?
Issue happens systematically, after a couple of timeouts raised (not always the same number)

### What is the expected behavior?

<!--
If possible please provide textual output instead of screenshots.
-->
```
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
Script execution timed out.
stdout bufferedRequestCount: 0
Needed to raise that many timeouts to show the problem: 10
Log in main still working
The previous line should be 'Log in main still working', if it is not, stdout seems to be broken...
```

### What do you see instead?

<!--
If possible please provide textual output instead of screenshots.
-->
```
Script execution timed out.
Script execution timed out.
Script execution timed out.
stdout bufferedRequestCount: 4564
Needed to raise that many timeouts to show the problem: 3
The previous line should be 'Log in main still working', if it is not, stdout seems to be broken...
```
### Additional information

<!--
Tell us anything else you think we should know.
-->

Some points that can be helpful:
- The issue is raised with `vm.runInContext`, `vm.runInNewContext`, `vm.runInThisContext`.
- The same issue happens with `process.stderr`, so it's not specific to `process.stdout`.
- No event (`error`, `drain`...) is emitted by  `process.stdout`.
- I could figure out that, when a timeout is raised (might not be the first one), `process.stdout` starts to buffer the `process.stdout.write` requests and  `process.stdout.write` calls will return `false`. When too many, `process.stdout` will eventually enter in `needDrain` mode. However, the `drain` event is never emitted. It looks like something prevents the data to be output on the terminal, the buffer of `process.stdout` is never processed, leaving  `process.stdout` in a `needDrain` mode forever.

Note that the actual code I want to run in my project is not exactly the snippet. It has no infinite loop, it just runs a piece of code that makes use of `console.log` to trace different steps, and it happens regularly that it timeouts. Hence, my project requires the capability to use `console.log`, have a timeout raised, and still be able to use `console.log` after that.

Any idea about this? Any workaround?