-
Notifications
You must be signed in to change notification settings - Fork 87
debug: fallback to mark breakpoints verified on stopped/breakpoint events #1989
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,6 +114,8 @@ export class LoggingDebugAdapterTracker implements vscode.DebugAdapterTracker { | |
| return; | ||
| } | ||
|
|
||
| this.handleBreakpointFallback(debugMessage); | ||
|
|
||
| if (debugMessage.event === "exited" && debugMessage.body.exitCode) { | ||
| this.exitCode = debugMessage.body.exitCode; | ||
| this.exitHandler?.(debugMessage.body.exitCode); | ||
|
|
@@ -131,6 +133,102 @@ export class LoggingDebugAdapterTracker implements vscode.DebugAdapterTracker { | |
| } | ||
| } | ||
|
|
||
| private handleBreakpointEvent(rawMsg: unknown): void { | ||
| try { | ||
| // Minimal typed view of the event payload we care about. | ||
| type FrameLike = { source?: { path?: string }; line?: number }; | ||
| type BodyLike = { | ||
| exitCode?: number; | ||
| category?: string; | ||
| output?: string; | ||
| reason?: string; | ||
| thread?: { frames?: FrameLike[] }; | ||
| source?: { path?: string }; | ||
| line?: number; | ||
| }; | ||
|
|
||
| const msg = rawMsg as { type?: string; event?: string; body?: BodyLike | undefined }; | ||
| if (!msg || msg.type !== "event") { | ||
| return; | ||
| } | ||
|
|
||
| // Case A: stopped event with reason = "breakpoint" | ||
| if (msg.event === "stopped" && msg.body?.reason === "breakpoint") { | ||
| const frames = msg.body.thread?.frames; | ||
| if (!Array.isArray(frames) || frames.length === 0) { | ||
| return; | ||
| } | ||
|
|
||
| const top = frames[0]; | ||
| const sourcePath = top?.source?.path; | ||
| const line = top?.line; | ||
| if (!sourcePath || typeof line !== "number") { | ||
| return; | ||
| } | ||
|
|
||
| const bpLine0 = line - 1; // VS Code uses 0-based lines | ||
|
|
||
| const breakpoints = vscode.debug.breakpoints.filter( | ||
| b => b instanceof vscode.SourceBreakpoint | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thought: we probably are ok since looks like a lot of tests passed, but something to keep in mind, is
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually I see you seem to have that check below, so ya we could simplify by either not performing the filter and let check below make sure we have a location, or if we check for location when filter we can drop that extra |
||
| ) as vscode.SourceBreakpoint[]; | ||
|
|
||
| for (const bp of breakpoints) { | ||
| const loc = bp.location; | ||
| if (!loc) { | ||
| continue; | ||
| } | ||
| if (loc.uri.fsPath !== sourcePath) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: does the DAP spec ensure that the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right — the DAP spec doesn’t guarantee absolute paths. I’ll normalize the path before comparing. |
||
| continue; | ||
| } | ||
| if (loc.range.start.line !== bpLine0) { | ||
| continue; | ||
| } | ||
|
|
||
| // Force a UI refresh so the breakpoint shows as installed. | ||
| vscode.debug.removeBreakpoints([bp]); | ||
| vscode.debug.addBreakpoints([bp]); | ||
| break; | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| // Case B: explicit "breakpoint" event that carries source+line info | ||
| if (msg.event === "breakpoint" && msg.body) { | ||
| const sourcePath = msg.body.source?.path; | ||
| const line = msg.body.line; | ||
| if (!sourcePath || typeof line !== "number") { | ||
| return; | ||
| } | ||
|
|
||
| const bpLine0 = line - 1; | ||
| const breakpoints = vscode.debug.breakpoints.filter( | ||
| b => b instanceof vscode.SourceBreakpoint | ||
| ) as vscode.SourceBreakpoint[]; | ||
|
|
||
| for (const bp of breakpoints) { | ||
| const loc = bp.location; | ||
| if (!loc) { | ||
| continue; | ||
| } | ||
| if (loc.uri.fsPath !== sourcePath) { | ||
| continue; | ||
| } | ||
| if (loc.range.start.line !== bpLine0) { | ||
| continue; | ||
| } | ||
|
|
||
| vscode.debug.removeBreakpoints([bp]); | ||
| vscode.debug.addBreakpoints([bp]); | ||
| break; | ||
| } | ||
| return; | ||
| } | ||
| } catch (err) { | ||
| // eslint-disable-next-line no-console | ||
| console.error("Breakpoint fallback error:", err); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: Let's get the logger into
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, I can move this into the tracker so it gets logged properly. |
||
| } | ||
| } | ||
|
|
||
| /** | ||
| * The debug adapter session is about to be stopped. Delete the session from | ||
| * the tracker | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: instead of defining these types ourselves, we already have "@vscode/debugprotocol" as a dependency in the package.json and can make use of
BreakpointEventand other types defined in there. That way the type checker can flag mismatches :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. I’ll switch to the types from @vscode/debugprotocol instead of redefining them.