Skip to content

Stop the process before terminating it - #39

Closed
nevse wants to merge 1 commit into
MattParkerDev:mainfrom
nevse:fix/terminate-a-running-debuggee
Closed

Stop the process before terminating it#39
nevse wants to merge 1 commit into
MattParkerDev:mainfrom
nevse:fix/terminate-a-running-debuggee

Conversation

@nevse

@nevse nevse commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Fixes #38.

ICorDebugProcess::Terminate needs the process synchronized. On a running debuggee it fails with CORDBG_E_PROCESS_NOT_SYNCHRONIZED (0x80131302), the exception is caught and logged, and the request answers success while the process keeps running. Stopping first is what Disconnect already does on its other branch, so this reuses the same TryIsRunning/TryStop pair.

The second change is TryComplete instead of Complete on the runtime event channel. Terminate() disposes whether or not the terminate worked, so terminate followed by disconnect disposes twice and the second one throws ChannelClosedException out of Dispose, surfaced as Failed to disconnect.

Measured over SharpDbgInMemory + DebugProtocolHost, launching a console app and killing it four ways:

what the client sends 534170d with this
terminate while stopped at a breakpoint killed killed
disconnect(terminateDebuggee: true) while stopped killed killed
terminate while running survives killed
disconnect(terminateDebuggee: true) while running survives killed

And disconnect after a terminate no longer fails.

SharpDbg.Cli.Tests 32 of 32, three times, and 32 of 32 on 534170d as a control. Two runs failed on the way there, one on each side. The one I captured is on your main rather than on this branch, and it is the environment: ServerNotAvailableException for a stale dotnet-diagnostic-*-socket in $TMPDIR. Every debuggee killed rather than detached leaves one behind, and after a while the next attach cannot connect - I had 129 dead ones to clear before the suite was reliable again.

No test: it needs a launched debuggee, and the only launch scaffolding is in #34. Once that lands this is a few lines on top of LaunchTests - happy to add it there, or here if you would rather have the test first.

I agree to the terms of contributing as stated here

ICorDebugProcess::Terminate needs the process synchronized. On a running
debuggee it fails with CORDBG_E_PROCESS_NOT_SYNCHRONIZED, the exception
is caught and logged, and the request answers success while the process
keeps running. Stopping first is what Disconnect already does for the
non-terminating path.

Terminate disposes whether or not the terminate worked, so a client that
sends terminate and then disconnect disposes twice and the second one
throws ChannelClosedException out of Dispose, surfaced as "Failed to
disconnect". TryComplete makes the second dispose harmless.
@MattParkerDev

Copy link
Copy Markdown
Owner

Thanks, implemented in 039f36e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

terminate leaves a running debuggee alive and reports success

2 participants