From 61951873b59b392b5d7ccc3ee09dad5bd0a305e9 Mon Sep 17 00:00:00 2001 From: "Kamat, Trivikram" <16024985+trivikr@users.noreply.github.com> Date: Wed, 27 May 2026 23:51:23 -0700 Subject: [PATCH] debugger: defer probe pause handling until startup Keep the initial --inspect-brk pause held until probe breakpoints are bound and probe mode explicitly releases the target. This prevents the generic pause handler from resuming user code before probes are ready. Refs: https://github.com/nodejs/node/actions/runs/26482141780/job/77981519238 Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.5 --- lib/internal/debugger/inspect_probe.js | 4 +++ .../test-debugger-probe-startup-pause.js | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/parallel/test-debugger-probe-startup-pause.js diff --git a/lib/internal/debugger/inspect_probe.js b/lib/internal/debugger/inspect_probe.js index fc9f3056f52341..9fb5ce1c281ae5 100644 --- a/lib/internal/debugger/inspect_probe.js +++ b/lib/internal/debugger/inspect_probe.js @@ -599,6 +599,9 @@ class ProbeInspectorSession { async handlePaused(params) { if (this.finished) { return; } + // Keep the initial --inspect-brk pause held until breakpoint setup is + // complete. `Runtime.runIfWaitingForDebugger` releases startup execution. + if (!this.started) { return; } const hitBreakpoints = params.hitBreakpoints; if (hitBreakpoints === undefined || hitBreakpoints.length === 0) { @@ -979,5 +982,6 @@ async function runProbeMode(stdout, probeOptions) { module.exports = { parseProbeTokens, + ProbeInspectorSession, runProbeMode, }; diff --git a/test/parallel/test-debugger-probe-startup-pause.js b/test/parallel/test-debugger-probe-startup-pause.js new file mode 100644 index 00000000000000..0cd9c5b18a4881 --- /dev/null +++ b/test/parallel/test-debugger-probe-startup-pause.js @@ -0,0 +1,32 @@ +// Flags: --expose-internals +// This tests that probe mode keeps the initial --inspect-brk pause held until +// startup has finished binding breakpoints. +'use strict'; + +const common = require('../common'); +common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const { ProbeInspectorSession } = require('internal/debugger/inspect_probe'); + +const session = new ProbeInspectorSession({ + probes: [], +}); + +const cdpCalls = []; +session.client = { + callMethod: common.mustCall(async (method) => { + cdpCalls.push(method); + }), +}; + +async function testStartupPauseHandling() { + await session.handlePaused({}); + assert.deepStrictEqual(cdpCalls, []); + + session.started = true; + await session.handlePaused({}); + assert.deepStrictEqual(cdpCalls, ['Debugger.resume']); +} + +testStartupPauseHandling().then(common.mustCall());