nodejs/test/parallel/test-inspector-async-call-stack.js
Joyee Cheung e2bc395c42
inspector: skip promise hook in the inspector async hook
Instead of filtering out promises in the async hooks added
for async task tracking, add an internal path to skip adding
the promise hook completely for the inspector async hook.
The actual user-land promise tracking is already handled by
V8 inspector. This prevents the internal promise hook from
showing up and creating unnecessary noise when stepping into
async execution in the inspector.

PR-URL: https://github.com/nodejs/node/pull/57148
Refs: https://issues.chromium.org/issues/390581540
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2025-02-23 01:07:21 +00:00

80 lines
3.3 KiB
JavaScript

// Flags: --expose-internals
'use strict';
const common = require('../common');
common.skipIfInspectorDisabled();
common.skipIf32Bits();
const assert = require('assert');
const { inspect } = require('util');
const { internalBinding } = require('internal/test/binding');
const { async_hook_fields, constants, getPromiseHooks } = internalBinding('async_wrap');
const { kTotals } = constants;
const inspector = require('inspector/promises');
const setDepth = 'Debugger.setAsyncCallStackDepth';
const emptyPromiseHooks = [ undefined, undefined, undefined, undefined ];
function verifyAsyncHookDisabled(message) {
assert.strictEqual(async_hook_fields[kTotals], 0,
`${async_hook_fields[kTotals]} !== 0: ${message}`);
const promiseHooks = getPromiseHooks();
assert.deepStrictEqual(
promiseHooks, emptyPromiseHooks,
`${message}: promise hooks ${inspect(promiseHooks)}`
);
}
function verifyAsyncHookEnabled(message) {
assert.strictEqual(async_hook_fields[kTotals], 4,
`${async_hook_fields[kTotals]} !== 4: ${message}`);
const promiseHooks = getPromiseHooks();
assert.deepStrictEqual( // Inspector async hooks should not enable promise hooks
promiseHooks, emptyPromiseHooks,
`${message}: promise hooks ${inspect(promiseHooks)}`
);
}
// By default inspector async hooks should not have been installed.
verifyAsyncHookDisabled('inspector async hook should be disabled at startup');
const session = new inspector.Session();
verifyAsyncHookDisabled('creating a session should not enable async hooks');
session.connect();
verifyAsyncHookDisabled('connecting a session should not enable async hooks');
(async () => {
await session.post('Debugger.enable');
verifyAsyncHookDisabled('enabling debugger should not enable async hooks');
await assert.rejects(session.post(setDepth, { invalid: 'message' }), { code: 'ERR_INSPECTOR_COMMAND' });
verifyAsyncHookDisabled('invalid message should not enable async hooks');
await assert.rejects(session.post(setDepth, { maxDepth: 'five' }), { code: 'ERR_INSPECTOR_COMMAND' });
verifyAsyncHookDisabled('invalid maxDepth (string) should not enable ' +
'async hooks');
await assert.rejects(session.post(setDepth, { maxDepth: NaN }), { code: 'ERR_INSPECTOR_COMMAND' });
verifyAsyncHookDisabled('invalid maxDepth (NaN) should not enable ' +
'async hooks');
await session.post(setDepth, { maxDepth: 10 });
verifyAsyncHookEnabled('valid message should enable async hooks');
await session.post(setDepth, { maxDepth: 0 });
verifyAsyncHookDisabled('Setting maxDepth to 0 should disable ' +
'async hooks');
await session.post(setDepth, { maxDepth: 32 });
verifyAsyncHookEnabled('valid message should enable async hooks');
await session.post('Debugger.disable');
verifyAsyncHookDisabled('Debugger.disable should disable async hooks');
await session.post('Debugger.enable');
verifyAsyncHookDisabled('Enabling debugger should not enable hooks');
await session.post(setDepth, { maxDepth: 64 });
verifyAsyncHookEnabled('valid message should enable async hooks');
await session.disconnect();
verifyAsyncHookDisabled('Disconnecting session should disable ' +
'async hooks');
})().then(common.mustCall());