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

Aberta
#192 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
3/5
Tempo estimado
1-2 dias
Facilidade para iniciantes
66/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
node.js, typescript
Domínio
devtools

Direção de pesquisa

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.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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.

Linguagem predominante
TypeScript
Estrelas
580
Forks
63
Merge médio
1d 17h
PRs com merge (30d)
11

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de microsoft/DebugMCP

Todas as issues de microsoft/DebugMCP

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.