What happens
The bundled netcoredbg (patched 3.2.0-1, 9744e1f) crashes with SIGSEGV when a session is stopped while its debuggee is still running out its final lines. It crashes after it has already answered terminate, and before it sends exited or terminated. The editor shows:
SharpLsp: netcoredbg exited unexpectedly (code null, signal SIGSEGV). Ending the debug session.
The debuggee is left behind, hung in its exit path, with ppid 1.
Reproduction
- The VS Code e2e suite
debug-evaluate-e2e (chunk debug-inspection) hits it on every run at the teardown of setVariable accepts what it can write and refuses what it cannot. Three runs out of three on macOS arm64.
- The test itself passes, because the crash happens after its assertions.
The DAP trace of the crashing session (SHARPLSP_DAP_TRACE=1) ends like this:
[dap->] continue {"threadId":…}
[dap<-] continue ok=true
[dap->] terminate {"restart":false}
[dap<-] terminate ok=true ← answered first
[dap<-] output "total=106" ← the debuggee is still running its last lines
… ~90 ms later: netcoredbg exited (signal SIGSEGV); no `exited`/`terminated` was ever sent
A session that does not crash, captured byte for byte, shows the healthy order: continue → stopped → exited → terminated → the terminate response.
So the crash looks like a race inside netcoredbg's terminate handling against a debuggee that is still running or exiting.
These did not reproduce it:
- Replaying the same request stream against netcoredbg directly, including the router's own async-debugging
setExpression arm step and the real StepTarget program. 40+ attempts.
- The same test with a logging shim in front of netcoredbg. The shim's latency hides it.
It needs the extension's real timing.
Impact
- Stopping a session at the wrong moment crashes the adapter, shows a crash message instead of a clean stop, and used to leave a hung debuggee behind.
- Leftover debuggees break
attach by process name ("matches 2 running processes").
Mitigation in SharpLsp (in progress on mtp-test-explorer-merge)
- The router now records the debuggee that netcoredbg names in its DAP
process event (startMethod: "launch").
- When the adapter dies without ending that debuggee, the router ends it itself (
dap-debuggee.ts, [DEBUG-ARCHITECTURE-ROUTER] "Adapter lifecycle"). An attached process is never touched.
- With that change the crash still happens, but it no longer leaves a process behind. Verified three runs out of three.
The crash itself remains open. It needs a netcoredbg-side fix: upstream, or in the pinned patch if the patch is involved.
What happens
The bundled netcoredbg (patched
3.2.0-1,9744e1f) crashes with SIGSEGV when a session is stopped while its debuggee is still running out its final lines. It crashes after it has already answeredterminate, and before it sendsexitedorterminated. The editor shows:The debuggee is left behind, hung in its exit path, with ppid 1.
Reproduction
debug-evaluate-e2e(chunkdebug-inspection) hits it on every run at the teardown ofsetVariable accepts what it can write and refuses what it cannot. Three runs out of three on macOS arm64.The DAP trace of the crashing session (
SHARPLSP_DAP_TRACE=1) ends like this:A session that does not crash, captured byte for byte, shows the healthy order:
continue→stopped→exited→terminated→ theterminateresponse.So the crash looks like a race inside netcoredbg's
terminatehandling against a debuggee that is still running or exiting.These did not reproduce it:
setExpressionarm step and the realStepTargetprogram. 40+ attempts.It needs the extension's real timing.
Impact
attachby process name ("matches 2 running processes").Mitigation in SharpLsp (in progress on
mtp-test-explorer-merge)processevent (startMethod: "launch").dap-debuggee.ts, [DEBUG-ARCHITECTURE-ROUTER] "Adapter lifecycle"). An attached process is never touched.The crash itself remains open. It needs a netcoredbg-side fix: upstream, or in the pinned patch if the patch is involved.