From c1da4e4aa4583c14f87c8d230ce7580f3b157ff0 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 1 Feb 2020 13:33:29 +0100 Subject: [PATCH] src: fix inspecting `MessagePort` from `init` async hook During the `init()` async hook, the C++ object is not finished creating yet (i.e. it is an `AsyncWrap`, but not yet a `HandleWrap` or `MessagePort`). Accessing the `handle_` field is not valid in that case. However, the custom inspect function for `MessagePort`s calls `HasRef()` on the object, which would crash when the object is not fully constructed. Fix that by guarding the access of the libuv handle on that condition. PR-URL: https://github.com/nodejs/node/pull/31600 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca --- src/handle_wrap.h | 4 +++- ...r-message-port-inspect-during-init-hook.js | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-worker-message-port-inspect-during-init-hook.js diff --git a/src/handle_wrap.h b/src/handle_wrap.h index 612874aa2ef..a555da9479d 100644 --- a/src/handle_wrap.h +++ b/src/handle_wrap.h @@ -61,7 +61,9 @@ class HandleWrap : public AsyncWrap { static void HasRef(const v8::FunctionCallbackInfo& args); static inline bool IsAlive(const HandleWrap* wrap) { - return wrap != nullptr && wrap->state_ != kClosed; + return wrap != nullptr && + wrap->IsDoneInitializing() && + wrap->state_ != kClosed; } static inline bool HasRef(const HandleWrap* wrap) { diff --git a/test/parallel/test-worker-message-port-inspect-during-init-hook.js b/test/parallel/test-worker-message-port-inspect-during-init-hook.js new file mode 100644 index 00000000000..30b90710a60 --- /dev/null +++ b/test/parallel/test-worker-message-port-inspect-during-init-hook.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common'); +const util = require('util'); +const assert = require('assert'); +const async_hooks = require('async_hooks'); +const { MessageChannel } = require('worker_threads'); + +// Regression test: Inspecting a `MessagePort` object before it is finished +// constructing does not crash the process. + +async_hooks.createHook({ + init: common.mustCall((id, type, triggerId, resource) => { + assert.strictEqual(util.inspect(resource), + 'MessagePort { active: true, refed: false }'); + }, 2) +}).enable(); + +const { port1 } = new MessageChannel(); +const inspection = util.inspect(port1); +assert(inspection.includes('active: true')); +assert(inspection.includes('refed: false'));