Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@
"command": "cdt.debug.setOutputRadixToDecimal",
"category": "CDT-GDB",
"title": "Set Global Output Radix to Decimal"
},
{
"title": "CDT-GDB: Set Hardware Breakpoint",
Comment thread
jreineckearm marked this conversation as resolved.
"command": "cdt.debug.breakpoints.addHardwareBreakpoint"
},
{
"title": "CDT-GDB: Set Software Breakpoint",
"command": "cdt.debug.breakpoints.addSoftwareBreakpoint"
}
],
"breakpoints": [
Expand Down Expand Up @@ -885,6 +893,24 @@
{
"command": "cdt.debug.setOutputRadixToDecimal",
"when": "inDebugMode"
},
{
"command": "cdt.debug.breakpoints.addHardwareBreakpoint",
"when": "false"
},
{
"command": "cdt.debug.breakpoints.addSoftwareBreakpoint",
"when": "false"
}
],
"editor/lineNumber/context": [
{
"command": "cdt.debug.breakpoints.addHardwareBreakpoint",
"group": "navigation"
},
{
"command": "cdt.debug.breakpoints.addSoftwareBreakpoint",
"group": "navigation"
}
]
}
Expand Down
78 changes: 78 additions & 0 deletions src/BreakpointModesController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*********************************************************************
* Copyright (c) 2026 Renesas Electronics Corporation and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*********************************************************************/
import {
ExtensionContext,
Position,
Location,
SourceBreakpoint,
commands,
debug,
window,
Uri,
} from 'vscode';
import { arePathsEqual } from './utils';

export class BreakpointModesController {
constructor(private context: ExtensionContext) {}

setBreakpointHandler =
(mode: 'hardware' | 'software') =>
async (values: { uri: Uri; lineNumber: number }) => {
try {
const line = values.lineNumber - 1;
Comment thread
jreineckearm marked this conversation as resolved.
const existingBreakpoints = debug.breakpoints.filter(
(bp: Partial<SourceBreakpoint>) =>
arePathsEqual(
bp?.location?.uri?.path,
values.uri.path,
) && bp?.location?.range?.start?.line === line,
);
if (existingBreakpoints.length) {
const existingBreakpointHasDesiredMode =
existingBreakpoints.findIndex(
(bp: any) => bp.mode === mode,
) > -1;
if (existingBreakpointHasDesiredMode) {
return;
}
debug.removeBreakpoints(existingBreakpoints);
}
const sp = new SourceBreakpoint(
new Location(values.uri, new Position(line, 0)),
);
// Limitation of VSCode: https://github.com/microsoft/vscode/issues/304764
// This is a workaround to inject 'mode' into VS breakpoint object.
// This injection functionally working as expected and passes the information
// correctly through DAP messages, however the breakpoint mode information is not
// visible in the breakpoint list window in VSCode
(sp as any).mode = mode;
debug.addBreakpoints([sp]);
} catch (e) {
window.showErrorMessage(
`Failed to set ${mode} breakpoint: ${e}`,
);
}
};

registerCommands = () => {
this.context.subscriptions.push(
commands.registerCommand(
'cdt.debug.breakpoints.addHardwareBreakpoint',
this.setBreakpointHandler('hardware'),
),
);
this.context.subscriptions.push(
commands.registerCommand(
'cdt.debug.breakpoints.addSoftwareBreakpoint',
this.setBreakpointHandler('software'),
),
);
};
}
3 changes: 3 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { CustomReset } from './CustomReset';
export { CustomReset } from './CustomReset';
import { SwitchRadix } from './switchRadix';
export { SwitchRadix } from './switchRadix';
import { BreakpointModesController } from './BreakpointModesController';

export function activate(context: ExtensionContext) {
new MemoryServer(context);
Expand All @@ -40,6 +41,8 @@ export function activate(context: ExtensionContext) {
});
}),
);
const breakpointModesController = new BreakpointModesController(context);
breakpointModesController.registerCommands();
}

export function deactivate() {
Expand Down
41 changes: 41 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*********************************************************************
* Copyright (c) 2026 Renesas Electronics Corporation and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*********************************************************************/
import { platform } from 'node:os';
import { normalize } from 'node:path';

/**
* This function compares the given paths, returns true if they are equal.
*
* - The compare function normalises the paths before checking, which means '.' and '..' expressions
* reduced properly.
* - For Windows, the compare function is case insensitive
* - For Windows, the compare function also handles backslashes, forward slashes insensitively.
* - Compare function handles undefined values, which means given paths can be undefined. No need to check
* undefined before sending the arguments.
*
* @param path1
* First path to compare
* @param path2
* Second path to compare
*/
export const arePathsEqual = (
path1: string | undefined,
path2: string | undefined,
): boolean => {
if (!path1 || !path2) {
return path1 === path2;
}
const nPath1 = normalize(path1);
const nPath2 = normalize(path2);
return platform() === 'win32'
? nPath1.localeCompare(nPath2, undefined, { sensitivity: 'accent' }) ===
0
: nPath1 === nPath2;
};
Loading