Skip to content

Commit b84e0d7

Browse files
christianaurichzmaduh95
authored andcommitted
test: deflake test-inspect-async-hook-setup-at-inspect
The test sends Debugger.setAsyncCallStackDepth in the same batch as Runtime.enable and Debugger.enable, and treats the command response as proof that async stack recording is on. It is not. While the target runs JS the command is dispatched from a V8 interrupt, where Agent::SyncAsyncHookState() cannot call into JS and defers enabling the async hook to an immediate, answering the command anyway. The `debugger` in the polling interval then pauses the target before that immediate runs, and the nested message loop does not process immediates, so setupTimeoutWithBreak() schedules the timer with the hook still disabled and Debugger.paused arrives without asyncStackTrace. Send the command after the first pause instead. Messages dispatched while the target is paused come from the nested message loop rather than an interrupt, so the hook is enabled inline and the response is the barrier the test assumed it to be. Deferring is deliberate: calling into JS from a V8 interrupt is not safe. This corrects an assumption of the test, not the runtime. Signed-off-by: Christian Aurich <christian.aurichzm@gmail.com> PR-URL: #65584 Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-08-26.md Refs: #65028 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 8916332 commit b84e0d7

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

test/parallel/test-inspect-async-hook-setup-at-inspect.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ async function waitForInitialSetup(session) {
2525
await session.waitForBreakOnLine(2, '[eval]');
2626
}
2727

28+
// Sent only once the target is paused. While the target runs JS the command
29+
// is dispatched from a V8 interrupt, where Agent::SyncAsyncHookState() cannot
30+
// call into JS and defers enabling the async hook to an immediate that the
31+
// pause then blocks, answering the command anyway. Dispatching from the paused
32+
// message loop enables the hook inline, so the response is a real barrier.
33+
async function enableAsyncStackTraces(session) {
34+
console.error('[test]', 'Enabling async stack traces');
35+
await session.send({ 'method': 'Debugger.setAsyncCallStackDepth',
36+
'params': { 'maxDepth': 10 } });
37+
}
38+
2839
async function setupTimeoutForStackTrace(session) {
2940
console.error('[test]', 'Setting up timeout for async stack trace');
3041
await session.send([
@@ -50,13 +61,12 @@ async function runTests() {
5061
await session.send([
5162
{ 'method': 'Runtime.enable' },
5263
{ 'method': 'Debugger.enable' },
53-
{ 'method': 'Debugger.setAsyncCallStackDepth',
54-
'params': { 'maxDepth': 10 } },
5564
{ 'method': 'Debugger.setBlackboxPatterns',
5665
'params': { 'patterns': [] } },
5766
]);
5867

5968
await waitForInitialSetup(session);
69+
await enableAsyncStackTraces(session);
6070
await setupTimeoutForStackTrace(session);
6171
await checkAsyncStackTrace(session);
6272

0 commit comments

Comments
 (0)