Skip to content

Commit

Permalink
src/debugAdapter: add 'panic' and 'fatal error' as stopped reasons
Browse files Browse the repository at this point in the history
Delve sets breakpoints in order to catch uncaught panics and fatal
throws when they happen. The extension was sending a stopped event
with reason breakpoint because it was stopped on a breakpoint, even
though it was not a user set breakpoint.

The extension will now check for these special breakpoints, and set
the reason for stopping as 'panic' and 'fatal error'.

Fixes golang#648

Change-Id: Ie72d35b2d02669cd011197c484cd0f99fbc57cc2
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/256939
Trust: Suzy Mueller <[email protected]>
Run-TryBot: Suzy Mueller <[email protected]>
TryBot-Result: kokoro <[email protected]>
Reviewed-by: Polina Sokolova <[email protected]>
  • Loading branch information
suzmue committed Sep 24, 2020
1 parent f9daaad commit 18cfe6e
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/debugAdapter/goDebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,14 @@ interface DiscardedBreakpoint {
reason: string;
}

// Unrecovered panic and fatal throw breakpoint IDs taken from delve:
// https://github.com/go-delve/delve/blob/f90134eb4db1c423e24fddfbc6eff41b288e6297/pkg/proc/breakpoints.go#L11-L21
// UnrecoveredPanic is the name given to the unrecovered panic breakpoint.
const unrecoveredPanicID = -1;
// FatalThrow is the name given to the breakpoint triggered when the target
// process dies because of a fatal runtime error.
const fatalThrowID = -2;

// This interface should always match the schema found in `package.json`.
interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
request: 'launch';
Expand Down Expand Up @@ -2203,7 +2211,18 @@ export class GoDebugSession extends LoggingDebugSession {
// Other stopping events (eg pause) create their own StoppedEvents,
// if necessary.
if (!!state.currentThread.breakPoint) {
this.handleReenterDebug('breakpoint');
const bp = state.currentThread.breakPoint;
if (bp.id === unrecoveredPanicID) {
// If the breakpoint is actually caused by a panic,
// we want to return on "panic".
this.handleReenterDebug('panic');
} else if (bp.id === fatalThrowID) {
// If the breakpoint is actually caused by a fatal throw,
// we want to return on "fatal error".
this.handleReenterDebug('fatal error');
} else {
this.handleReenterDebug('breakpoint');
}
}
};

Expand Down

0 comments on commit 18cfe6e

Please sign in to comment.