A second standalone CLI launch reports completion while the new session is paused

Ouverte
#192 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
66/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
node.js, typescript
Domaine
devtools

Piste de recherche

Read src/debuggingHandler.ts around handleStartDebugging and src/cli/cliDebuggingExecutor.ts around waitForDebugSessionReady and readyState. Run the linked CLI readiness regression harness against the pinned commit, then compare the reused handler's second start after stop and normal completion with the fresh executor control. Done when each new launch reports the readiness outcome from its own session and the regression passes.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Summary

Reusing one standalone CLI handler after a debug session ends makes the next
start_debugging response describe that previous session's termination. The new
session starts normally and hits its breakpoint, but the response says that it
"ran to completion without stopping". Its embedded state simultaneously reports
an active, paused session.

This concerns the standalone CLI executor and handler. It does not reproduce a
VS Code launch or rely on editor focus or VS Code's selected frame.

Environment

  • DebugMCP source commit: d0b4a334a6a3d8d600c5aa75ec60d9de272af3c4.
  • The root package manifest at this commit reports extension version 2.4.4.
  • Verified baseline: Windows x64, Node.js 24.22.1 and the repository's compiled
    out/ modules.
  • A bounded synthetic Node DAP adapter communicating over standard input/output.
    The adapter starts no debuggee and requires no installed language debugger.

The test emits the actual checkout commit, Node version, source/compiled-module
hashes, session IDs and fixture-process IDs. IDs are assigned during the run;
no particular process or session ID is a reproduction prerequisite.

Reproduction steps

  1. In a writable working directory, create a separate upstream checkout and build the reviewed commit. The following commands use PowerShell:

    $debugMcpRoot = Join-Path (Get-Location) 'DebugMCP-review-target'
    git clone https://github.com/microsoft/DebugMCP.git $debugMcpRoot
    git -C $debugMcpRoot checkout d0b4a334a6a3d8d600c5aa75ec60d9de272af3c4
    Push-Location $debugMcpRoot
    npm ci --ignore-scripts
    npm run compile
    Pop-Location
    
  2. Obtain the reproduction project from its default main branch, then run the regression against the upstream checkout:

    $reproRoot = Join-Path (Get-Location) 'debugmcp-review-repro'
    git clone https://github.com/hahnfk/debugmcp-repro.git $reproRoot
    Push-Location $reproRoot
    node scripts/review/cli-second-start-readiness.cjs --debugmcp-root $debugMcpRoot
    Pop-Location
    

    Sources and evidence: Regression harness, Module loader, Synthetic DAP adapter, Recorded results.

  3. The test constructs the actual CliDebuggingExecutor and DebuggingHandler
    with the actual DapClient. It saves one breakpoint through the public
    handler and starts the synthetic adapter. The adapter performs
    initialize → launch → initialized → setBreakpoints → configurationDone → stopped.
    The first start reports the breakpoint stop correctly.

  4. It ends that first session using stop_debugging, confirms the executor is
    inactive, and starts again through the same handler with the same saved
    breakpoint. The new adapter delivers another real DAP stopped event.

  5. It repeats the comparison after normal completion via continue_execution.
    An independent fresh-executor first start is an additional positive control.

The default command checks the expected fixed behavior and exits nonzero on the
reviewed commit. To require the exact current bug together with the positive
controls and successful process cleanup, add --expect-current-bug:

node (Join-Path $reproRoot 'scripts/review/cli-second-start-readiness.cjs') --debugmcp-root $debugMcpRoot --expect-current-bug

An arbitrary startup failure does not count as reproducing the bug.

Expected result

Every new launch should wait for and describe that launch's readiness outcome.
Both starts above hit the saved breakpoint, so each response should report a
breakpoint stop with sessionActive: true and paused: true.

Actual result

The first start reports a breakpoint stop. After the first session ends, the
second response says:

Debug session for <fixture-path> ran to completion without stopping (no breakpoint hit).

The same response's state describes the new session:

{
  "sessionActive": true,
  "paused": true,
  "configurationName": "review CLI readiness"
}

An independent state request confirms that the second session is active and
paused. Its session ID differs from the first session's ID. Both the explicit
stop and normal-completion cases exhibit the mismatch; a fresh executor's first
start remains a successful positive control.

Cause and scope

handleStartDebugging
creates its readiness promise before starting the next session. The CLI
waitForDebugSessionReady
immediately returns an existing ready state. After a previous run,
readyState
returns terminated. That already-resolved promise is then used for the new
launch even though its state has advanced to a new active session.

The reproduction exercises production executor, handler and DAP-client methods
without writing private fields or replacing their methods. Its test seams are
the synthetic DAP adapter, a deterministic configuration-manager double supplying
the same launch configuration, the loader's inert vscode import and its quiet
logger sink. No VS Code window, language extension or real debuggee is controlled.
Fixture processes exit on continue/disconnect, closed input or their own
15-second deadline. Normal cleanup uses executor.dispose(), which closes the
adapter through its owned child-process handle. The harness has a separate
20-second deadline and reports remaining process IDs without killing by PID.

For the recorded baseline, use the clean pinned checkout above. The harness also
accepts a rebuilt local fix, reports sourceDirty and module hashes, and applies
the normal regression oracle when --expect-current-bug is omitted.

Related reports

  • Issue #161 and merged
    PR #162 address breakpoint
    synchronization after session termination by clearing initialized.
    Breakpoint editing between sessions works in this reproduction. The remaining
    mismatch is the readiness result selected for the second launch.
  • This draft reports source behavior at the pinned commit. It makes no claim
    about which npm package versions have been published or installed.

Investigation tooling

This investigation and its reproduction work were carried out with assistance
from OpenAI Codex.

  • Codex desktop app version: 26.1021.31345 (build 21828).
  • Version verified on 2026-10-25, when this tooling disclosure was added.

The automated reproduction runs directly as an isolated Node.js harness against
the DebugMCP implementation. Codex assisted the investigation, harness authoring
and report preparation.

Langage dominant
TypeScript
Étoiles
580
Forks
63
Merge moyen
1 j 17 h
PR mergées (30 j)
11

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de microsoft/DebugMCP

Toutes les issues de microsoft/DebugMCP

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.