Skip to content

Commit e7efba0

Browse files
authored
Add support to notify VSC Debugger when status of a breakpoint changes (#989)
Fixes #87
1 parent d7f272d commit e7efba0

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

news/2 Fixes/87.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix occasionally having unverified breakpoints

src/client/debugger/Main.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if ((Reflect as any).metadata === undefined) {
99
}
1010
import * as fs from "fs";
1111
import * as path from "path";
12-
import { Handles, InitializedEvent, OutputEvent, Scope, Source, StackFrame, StoppedEvent, TerminatedEvent, Thread, Variable, LoggingDebugSession, logger } from "vscode-debugadapter";
12+
import { Handles, InitializedEvent, OutputEvent, Scope, Source, StackFrame, StoppedEvent, TerminatedEvent, Thread, Variable, LoggingDebugSession, logger, BreakpointEvent, Breakpoint } from "vscode-debugadapter";
1313
import { ThreadEvent } from "vscode-debugadapter";
1414
import { DebugProtocol } from "vscode-debugprotocol";
1515
import { DEBUGGER } from '../../client/telemetry/constants';
@@ -126,6 +126,7 @@ export class PythonDebugger extends LoggingDebugSession {
126126
pythonProcess.on("output", (pyThread, output) => this.onDebuggerOutput(pyThread, output, 'stdout'));
127127
pythonProcess.on("exceptionRaised", (pyThread, ex) => this.onPythonException(pyThread, ex));
128128
pythonProcess.on("breakpointHit", (pyThread, breakpointId) => this.onBreakpointHit(pyThread, breakpointId));
129+
pythonProcess.on("breakpointChanged", (breakpointId: number, verified: boolean) => this.onBreakpointChanged(breakpointId, verified));
129130
pythonProcess.on("stepCompleted", (pyThread) => this.onStepCompleted(pyThread));
130131
pythonProcess.on("detach", () => this.onDetachDebugger());
131132
pythonProcess.on("error", ex => this.onDebuggerOutput(undefined, ex, 'stderr'));
@@ -326,6 +327,16 @@ export class PythonDebugger extends LoggingDebugSession {
326327
this.pythonProcess!.SendResumeThread(pyThread.Id);
327328
}
328329
}
330+
private onBreakpointChanged(breakpointId: number, verified: boolean) {
331+
if (!this.registeredBreakpoints.has(breakpointId)) {
332+
return;
333+
}
334+
const pythonBkpoint = this.registeredBreakpoints.get(breakpointId)!;
335+
const breakpoint = new Breakpoint(verified, pythonBkpoint.LineNo, undefined, new Source(path.basename(pythonBkpoint.Filename), pythonBkpoint.Filename));
336+
// VSC needs `id` to uniquely identify each breakpoint (part of the protocol spec).
337+
(breakpoint as any).id = pythonBkpoint.Id;
338+
this.sendEvent(new BreakpointEvent('changed', breakpoint));
339+
}
329340
private buildBreakpointDetails(filePath: string, line: number, condition: string): IPythonBreakpoint {
330341
let isDjangoFile = false;
331342
if (this.launchArgs &&
@@ -360,7 +371,8 @@ export class PythonDebugger extends LoggingDebugSession {
360371
this.registeredBreakpointsByFileName.set(args.source.path!, []);
361372
}
362373

363-
const breakpoints: { verified: boolean, line: number }[] = [];
374+
// VSC needs `id` to uniquely identify each breakpoint (part of the protocol spec).
375+
const breakpoints: { verified: boolean, line: number, id: number }[] = [];
364376
const linesToAdd = args.breakpoints!.map(b => b.line);
365377
const registeredBks = this.registeredBreakpointsByFileName.get(args.source.path!)!;
366378
const linesToRemove = registeredBks.map(b => b.LineNo).filter(oldLine => linesToAdd.indexOf(oldLine) === -1);
@@ -385,12 +397,12 @@ export class PythonDebugger extends LoggingDebugSession {
385397

386398
this.pythonProcess!.BindBreakpoint(breakpoint).then(() => {
387399
this.registeredBreakpoints.set(breakpoint.Id, breakpoint);
388-
breakpoints.push({ verified: true, line: bk.line });
400+
breakpoints.push({ verified: true, line: bk.line, id: breakpoint.Id });
389401
registeredBks.push(breakpoint);
390402
resolve();
391403
}).catch(reason => {
392404
this.registeredBreakpoints.set(breakpoint.Id, breakpoint);
393-
breakpoints.push({ verified: false, line: bk.line });
405+
breakpoints.push({ verified: false, line: bk.line, id: breakpoint.Id });
394406
registeredBks.push(breakpoint);
395407
resolve();
396408
});

src/client/debugger/PythonProcess.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,7 @@ export class PythonProcess extends EventEmitter implements IPythonProcess {
239239
// Find the last breakpoint command associated with this breakpoint
240240
let index = this.breakpointCommands.findIndex(item => item.Id === breakpointId);
241241
if (index === -1) {
242-
// Hmm this is not possible, log this exception and carry on
243-
// this.emit("error", "command.breakpoint.hit", `Uknown Breakpoit Id ${breakpointId}`);
242+
this.emit('breakpointChanged', breakpointId, success);
244243
return;
245244
}
246245

0 commit comments

Comments
 (0)