Description
- Version: v2.2.0+ (?)
- Platform: all
- Subsystem: process
The following exits without printing:
node -e "process.on('beforeExit', () => process._rawDebug('hi'))"
However, this does print:
node -e "process.on('beforeExit', () => process._rawDebug('hi')); setImmediate(()=>{})"
I did some debugging and using this patch I get the following output:
diff --git a/lib/events.js b/lib/events.js
index d676580..16ee82c 100644
--- a/lib/events.js
+++ b/lib/events.js
@@ -138,6 +138,8 @@ EventEmitter.prototype.emit = function emit(type) {
var needDomainExit = false;
var doError = (type === 'error');
+ // process._rawDebug((new Error()).stack)
+
events = this._events;
if (events)
doError = (doError && events.error == null);
@@ -169,6 +171,9 @@ EventEmitter.prototype.emit = function emit(type) {
handler = events[type];
+ process._rawDebug('01.5:' + type)
+ process._rawDebug(typeof handler)
+
if (!handler)
return false;
@@ -234,6 +239,9 @@ function _addListener(target, type, listener, prepend) {
}
if (!existing) {
+ process._rawDebug('@@@@')
+ // process._rawDebug((new Error()).stack)
+ // process._rawDebug(listener.toString())
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
diff --git a/lib/internal/process/next_tick.js b/lib/internal/process/next_tick.js
index 529645a..5f43ba0 100644
--- a/lib/internal/process/next_tick.js
+++ b/lib/internal/process/next_tick.js
@@ -138,6 +138,8 @@ function setupNextTick() {
}
function nextTick(callback) {
+ process._rawDebug('#####')
+ process._rawDebug((new Error()).stack)
if (typeof callback !== 'function')
throw new TypeError('callback is not a function');
// on the way out, don't bother. it won't get fired anyway.
./node -e "process.on('beforeExit', () => process._rawDebug('hi'))"
@@@@
@@@@
01.5:newListener
function
@@@@
#####
Error
at process.nextTick (internal/process/next_tick.js:142:24)
at evalScript (bootstrap_node.js:344:13)
at run (bootstrap_node.js:110:11)
at run (bootstrap_node.js:382:7)
at startup (bootstrap_node.js:109:9)
at bootstrap_node.js:497:3
01.5:beforeExit
undefined
01.5:newListener
function
@@@@
01.5:exit
undefined
That is, beforeExit
fires before the listener is attached.
Turns out that at evalScript (bootstrap_node.js:344:13)
leads to this code and comment in evalScript()
:
// Defer evaluation for a tick. This is a workaround for deferred
// events not firing when evaluating scripts from the command line,
// see https://github.com/nodejs/node/issues/1600.
process.nextTick(function() {
const result = module._compile(script, `${name}-wrapper`);
if (process._print_eval) console.log(result);
});
That comment leads back to #1600 - net.listen does not emit 'listening' event when in --eval mode
.
That was fixed in 93a44d5 by @bnoordhuis and reviewed by @trevnorris resulting in this code in evalScript()
.
Not sure how to fix this right now, but it seems like a deeper bug somewhere relating to startup and nextTick.
Refs: #1793 & #1600 & also the older nodejs/node-v0.x-archive#14168
Edit: found by @cxreg