Skip to content

Commit 2c73aa8

Browse files
committed
run w/o debugging
1 parent 2436b4d commit 2c73aa8

File tree

6 files changed

+85
-48
lines changed

6 files changed

+85
-48
lines changed

CHANGELOG.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,28 @@ New Features
88
<img src=https://user-images.githubusercontent.com/41269583/132694054-e4a2e085-132c-4bac-9c79-f5fdbdd9b1f8.png width=200 />
99

1010
* The only place we could put the `Reset` button was at the beginning. We would have rather put it closer to the end but there isn't an API to do that as far as we know. Note that the toolbar appears in docking and floating modes and it is the docking mode where this was not possible. Hopefully, it is not a hinderance.
11-
* Some gdb-servers do not respond appropriately to being reset to be compatible with `gdb`. You will have to find out what set of gdb-server/gdb commands work for you and use appropriate options in the `launch.json`. For instance, just after 'reset halt' some versions of OpenOCD do not provide `gdb` the updated registers (SP, PC, LR, etc.). Some devices may have a more complicated, customized reset mechanism, boot-loaders, etc. To force a synchronization between `OpenOCD` and `gdb`, you can do the following in `launch.json`.
12-
* `svdAddrGapThreshold` `launch.json` option. Normally adjacent register addresses with small gaps are combined to reduce the number of device memory reads. Default is 16 bytes. You can now control the number of bytes the gap can be including zero. Zero means strict reading of bytes but adjacent registers are still combined if there is no gap.
13-
14-
```
15-
"postRestartSessionCommands": [
16-
"monitor gdb_sync",
17-
"stepi" // Because of the command above, this is a no-op. No code is actually executed
18-
]
11+
* `Restart` causes VSCode to clear the `Debug Console` but `Reset` does not do that as VSCode is not involved.
12+
* Some gdb-servers do not respond appropriately to being reset and are not compatible with `gdb` expectations. You will have to find out what set of gdb-server/gdb commands work for you and use appropriate options in the `launch.json`. For instance, just after 'reset halt' some versions of OpenOCD do not provide `gdb` the updated registers (SP, PC, LR, etc.). Some devices may have a more complicated, customized reset mechanism, boot-loaders, etc. To force a synchronization between `OpenOCD` and `gdb`, you can do the following in `launch.json`.
1913
```
20-
* **Auto-continue**: Operations `Launch`, `Reset`, and `Restart` will issue a `continue` to gdb upon sussesful reset-halt. For `Launch` this is not done if `runToEntryPoint` has been enabled. It is also not done if the corresponding action has a post-session-start commands set (i.e., `postStartSessionCommands`, `postRestartSessionCommands`). This does not apply to `Attach` since that always stops on an successful `Attach`. You can disable the auto-continue behavior using `doNotContinueAfterReset`
14+
"postRestartSessionCommands": [ // OpenOCD only
15+
"monitor gdb_sync",
16+
"stepi" // Because of the command above, this is a no-op. No code is actually executed
17+
]
18+
```
19+
* **`Run Without Debugging (^F5)`**: Experimental. This will now work but VSCode does not clearly define what this button should do. In an embedded cases, that is even murkier because without GDB and a gdb-server, there is no way to start the program. Between VSCode and Cortex-Debug, the end result is as follows
20+
* VSCode does not transmit any breakpoints to Cortex-Debug and hence no breakpoints
21+
* VSCode does show a pause button in active mode but pressing on it does nothing because that action is not sent to Cortex-Debug
22+
* `runToEntryPoint` is disregarded and there will not be a stop after a Reset either
23+
* If however your program halts because of an exception or any other reason, it is handled normally and now you will enter the normal debugger
24+
* You can still Restart/Reset and the program restarts and continues to run
25+
26+
* **Auto-continue**: New behavior. Operations `Launch`, `Reset`, and `Restart` will now issue a `continue` to gdb upon sussesful reset-halt. This is not done in the followin cases
27+
* `runToEntryPoint` has been used for a `Launch` session or it is an `Attach` session
28+
* If a post-session-start commands (i.e., `postStartSessionCommands`, `postRestartSessionCommands`) are used; you can insert the `continue` command in there.
29+
* Or you have used the `"breakAfterReset" = true`
30+
31+
* `svdAddrGapThreshold` option in `launch.json` option. Normally adjacent register addresses with small gaps are combined to reduce the number of device memory reads. Default is 16 bytes. You can now control the number of bytes the gap can be including zero. Zero means strict reading of bytes but adjacent registers are still combined if there is no gap.
32+
2133
* JLinkGDBServer will no longer display a graphical progress bar at `Launch`. If you need it, you can use the `-gui` command-line option in `launch.json`'s `serverArgs`
2234

2335
# V0.4.3

debug_attributes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
| Attribute | Applies To | Description |
22
| --------- | ---------- | ----------- |
3+
| breakAfterReset | Common | Applies to Restart/Reset/Launch, halt debugger after a reset. Ignored for `Launch` if `runToEntryPoint` is used
34
| cmsisPack | Common | Path to a CMSIS-Pack file. Use to add extra device support.
45
| cwd | Common | Path of project
56
| debuggerArgs | Common | Additional arguments to pass to GDB command line
67
| device | Common | Target Device Identifier
7-
| doNotContinueAfterReset | Common | Do not 'continue' execution after a 'Launch', 'Reset' or 'Restart'. Program will stop at the reset-vector instead
88
| executable | Common | Path of executable
99
| gdbPath | Common | This setting can be used to overrride the GDB path user/workspace setting for a particular launch configuration. This should be the full pathname to the executable (or name of the executable if it is in your PATH). Note that other toolchain executables with the configured prefix must still be available.
1010
| graphConfig | Common | (unknown)

package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,10 @@
335335
"items": "string",
336336
"description": "Additional GDB Commands to be executed at the end of the re-start sequence, after a debug session has already started."
337337
},
338-
"doNotContinueAfterReset": {
338+
"breakAfterReset": {
339339
"default": false,
340340
"type": "boolean",
341-
"description": "Do not 'continue' execution after a 'Launch', 'Reset' or 'Restart'. Program will stop at the reset-vector instead"
341+
"description": "Applies to Restart/Reset/Launch, halt debugger after a reset."
342342
},
343343
"overrideGDBServerStartedRegex": {
344344
"description": "You can supply a regular expression (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) in the configuration property to override the output from the GDB server that is looked for to determine if the GDB server has started. Under most circumstances this will not be necessary - but could be needed as a result of a change in the output of a GDB server making it incompatible with cortex-debug. This property has no effect for bmp or external GDB server types.",
@@ -1160,10 +1160,10 @@
11601160
"items": "string",
11611161
"description": "Additional GDB Commands to be executed at the end of the re-start sequence, after a debug session has already started."
11621162
},
1163-
"doNotContinueAfterReset": {
1163+
"breakAfterReset": {
11641164
"default": false,
11651165
"type": "boolean",
1166-
"description": "Do not 'continue' execution after a 'Launch', 'Reset' or 'Restart'. Program will stop at the reset-vector instead"
1166+
"description": "Applies to Restart/Reset/Launch, halt debugger after a reset. Ignored for `Launch` if `runToEntryPoint` is used"
11671167
},
11681168
"overrideGDBServerStartedRegex": {
11691169
"description": "You can supply a regular expression (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) in the configuration property to override the output from the GDB server that is looked for to determine if the GDB server has started. Under most circumstances this will not be necessary - but could be needed as a result of a change in the output of a GDB server making it incompatible with cortex-debug. This property has no effect for bmp or external GDB server types.",
@@ -2053,6 +2053,10 @@
20532053
{
20542054
"command": "cortex-debug.setForceDisassembly",
20552055
"when": "debugType == cortex-debug"
2056+
},
2057+
{
2058+
"command": "cortex-debug.resetDevice",
2059+
"when": "debugType == cortex-debug"
20562060
}
20572061
],
20582062
"debug/toolBar": [

src/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export interface ConfigurationArguments extends DebugProtocol.LaunchRequestArgum
182182
postStartSessionCommands: string[];
183183
postRestartSessionCommands: string[];
184184
overrideGDBServerStartedRegex: string;
185-
doNotContinueAfterReset: boolean;
185+
breakAfterReset: boolean;
186186
svdFile: string;
187187
svdAddrGapThreshold: number;
188188
rttConfig: RTTConfiguration;

src/frontend/extension.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export class CortexDebugExtension {
4949
private SVDDirectory: SVDInfo[] = [];
5050
private functionSymbols: SymbolInformation[] = null;
5151
private debuggerStatus: 'started' | 'stopped' | 'running' | 'none';
52+
private currentArgs: any = null;
5253

5354
constructor(private context: vscode.ExtensionContext) {
5455
this.startServerConsole(context); // Make this the first thing we do so it is ready for the session
@@ -162,7 +163,9 @@ export class CortexDebugExtension {
162163
if (this.debuggerStatus === 'running') {
163164
vscode.window.showInformationMessage(msg);
164165
} else {
165-
this.registerProvider.refresh();
166+
if (this.currentArgs && !this.currentArgs.noDebug) {
167+
this.registerProvider.refresh();
168+
}
166169
}
167170
}
168171
}
@@ -437,7 +440,9 @@ export class CortexDebugExtension {
437440
}
438441

439442
private registersRefresh(): void {
440-
this.registerProvider.refresh();
443+
if (this.currentArgs && !this.currentArgs.noDebug) {
444+
this.registerProvider.refresh();
445+
}
441446
}
442447

443448
// Settings changes
@@ -485,6 +490,7 @@ export class CortexDebugExtension {
485490
this.debuggerStatus = 'started';
486491

487492
session.customRequest('get-arguments').then((args) => {
493+
this.currentArgs = args;
488494
let svdfile = args.svdFile;
489495
if (!svdfile) {
490496
svdfile = this.getSVDFile(args.device);
@@ -495,8 +501,10 @@ export class CortexDebugExtension {
495501
if (this.swoSource) { this.initializeSWO(args); }
496502
if (Object.keys(this.rttPortMap).length > 0) { this.initializeRTT(args); }
497503

498-
this.registerProvider.debugSessionStarted();
499-
this.peripheralProvider.debugSessionStarted(svdfile ? svdfile : null, args.svdAddrGapThreshold);
504+
if (!this.currentArgs.noDebug) {
505+
this.registerProvider.debugSessionStarted();
506+
}
507+
this.peripheralProvider.debugSessionStarted((svdfile && !args.noDebug) ? svdfile : null, args.svdAddrGapThreshold);
500508
this.cleanupRTTTerminals();
501509
}, (error) => {
502510
// TODO: Error handling for unable to get arguments
@@ -510,7 +518,9 @@ export class CortexDebugExtension {
510518
Reporting.endSession();
511519

512520
this.debuggerStatus = 'none';
513-
this.registerProvider.debugSessionTerminated();
521+
if (!this.currentArgs.noDebug) {
522+
this.registerProvider.debugSessionTerminated();
523+
}
514524
this.peripheralProvider.debugSessionTerminated();
515525
if (this.swo) {
516526
this.swo.debugSessionTerminated();
@@ -534,6 +544,7 @@ export class CortexDebugExtension {
534544
this.rttPortMap = {};
535545

536546
this.clearAdapterOutputChannel = true;
547+
this.currentArgs = null;
537548
}
538549
catch (e) {
539550
vscode.window.showInformationMessage(`Debug session did not terminate cleanly ${e}\n${e ? e.stackstrace : ''}. Please report this problem`);
@@ -570,7 +581,9 @@ export class CortexDebugExtension {
570581
private receivedStopEvent(e) {
571582
this.debuggerStatus = 'stopped';
572583
this.peripheralProvider.debugStopped();
573-
this.registerProvider.debugStopped();
584+
if (this.currentArgs && !this.currentArgs.noDebug) {
585+
this.registerProvider.debugStopped();
586+
}
574587
vscode.workspace.textDocuments.filter((td) => td.fileName.endsWith('.cdmem'))
575588
.forEach((doc) => { this.memoryProvider.update(doc); });
576589
if (this.swo) { this.swo.debugStopped(); }
@@ -580,7 +593,9 @@ export class CortexDebugExtension {
580593
private receivedContinuedEvent(e) {
581594
this.debuggerStatus = 'running';
582595
this.peripheralProvider.debugContinued();
583-
this.registerProvider.debugContinued();
596+
if (this.currentArgs && !this.currentArgs.noDebug) {
597+
this.registerProvider.debugContinued();
598+
}
584599
if (this.swo) { this.swo.debugContinued(); }
585600
if (this.rtt) { this.rtt.debugContinued(); }
586601
}

src/gdb.ts

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ export class GDBDebugSession extends DebugSession {
108108
protected trimCWD: string;
109109
protected switchCWD: string;
110110
protected started: boolean;
111-
protected crashed: boolean;
112111
protected debugReady: boolean;
113112
protected miDebugger: MI2;
114113
protected commandServer: net.Server;
@@ -293,7 +292,6 @@ export class GDBDebugSession extends DebugSession {
293292
this.quit = false;
294293
this.attached = false;
295294
this.started = false;
296-
this.crashed = false;
297295
this.debugReady = false;
298296
this.stopped = false;
299297
this.activeThreadIds.clear();
@@ -458,7 +456,7 @@ export class GDBDebugSession extends DebugSession {
458456
this.handleMsg('log', dbgMsg);
459457
}
460458

461-
this.disableSendStoppedEvents = (!attach && this.args.runToEntryPoint) ? true : false;
459+
this.disableSendStoppedEvents = (!attach && (this.args.runToEntryPoint || this.args.noDebug)) ? true : false;
462460
this.miDebugger.connect(this.args.cwd, this.args.executable, commands).then(() => {
463461
this.started = true;
464462
this.serverController.debuggerLaunchCompleted();
@@ -467,13 +465,15 @@ export class GDBDebugSession extends DebugSession {
467465

468466
const launchComplete = () => {
469467
this.disableSendStoppedEvents = false;
470-
setTimeout(() => {
471-
this.stopped = true;
472-
this.stoppedReason = 'start';
473-
this.stoppedThreadId = this.currentThreadId;
474-
this.sendEvent(new StoppedEvent('start', this.currentThreadId, true));
475-
this.sendEvent(new CustomStoppedEvent('start', this.currentThreadId));
476-
}, 50);
468+
if (!this.args.noDebug) {
469+
setTimeout(() => {
470+
this.stopped = true;
471+
this.stoppedReason = 'start';
472+
this.stoppedThreadId = this.currentThreadId;
473+
this.sendEvent(new StoppedEvent('start', this.currentThreadId, true));
474+
this.sendEvent(new CustomStoppedEvent('start', this.currentThreadId));
475+
}, 50);
476+
}
477477
};
478478

479479
const runPostStartSession = () => {
@@ -486,7 +486,7 @@ export class GDBDebugSession extends DebugSession {
486486
}
487487
};
488488

489-
if (this.args.runToEntryPoint) {
489+
if (!this.args.noDebug && this.args.runToEntryPoint) {
490490
this.miDebugger.sendCommand(`break-insert -t --function ${this.args.runToEntryPoint}`).then(() => {
491491
this.miDebugger.once('generic-stopped', launchComplete);
492492
// To avoid race conditions between finishing configuration, we should stay
@@ -585,11 +585,12 @@ export class GDBDebugSession extends DebugSession {
585585
break;
586586
}
587587

588-
// Note that for commands, an empty array is totall valid. Meaning don't do anything. Not even a 'continue'
589-
if (!this.args.doNotContinueAfterReset) {
590-
if ((commands == null) && (mode !== SessionMode.ATTACH) && !((mode === SessionMode.LAUNCH) && this.args.runToEntryPoint)) {
591-
commands = ['-exec-continue'];
592-
}
588+
if ((mode !== SessionMode.ATTACH) && this.args.noDebug) {
589+
if (!commands) { commands = []; }
590+
commands.push('-exec-continue');
591+
} else if (!this.args.breakAfterReset && (mode !== SessionMode.ATTACH) && (!commands || (commands.length === 0))) {
592+
// This function is not called if 'runToEntryPoint' was used
593+
commands = ['-exec-continue'];
593594
}
594595

595596
if (commands && (commands.length > 0)) {
@@ -989,13 +990,15 @@ export class GDBDebugSession extends DebugSession {
989990
this.sendResponse(response);
990991
setTimeout(() => {
991992
const isReset = (args as any).isReset;
992-
this.stopped = true; // This should aleady be true??
993-
this.stoppedReason = isReset ? 'reset' : 'restart';
994-
this.sendEvent(new ContinuedEvent(this.currentThreadId, true));
995-
this.sendEvent(new StoppedEvent(this.stoppedReason, this.currentThreadId, true));
996-
this.sendEvent(new CustomStoppedEvent(this.stoppedReason, this.currentThreadId));
997-
this.runPostStartSessionCommands(isReset ? SessionMode.RESET : SessionMode.RESTART, 50);
998-
}, 50);
993+
if (!this.args.noDebug) {
994+
this.stopped = true; // This should aleady be true??
995+
this.stoppedReason = isReset ? 'reset' : 'restart';
996+
this.sendEvent(new ContinuedEvent(this.currentThreadId, true));
997+
this.sendEvent(new StoppedEvent(this.stoppedReason, this.currentThreadId, true));
998+
this.sendEvent(new CustomStoppedEvent(this.stoppedReason, this.currentThreadId));
999+
}
1000+
this.runPostStartSessionCommands(isReset ? SessionMode.RESET : SessionMode.RESTART);
1001+
}, 5);
9991002
}, (msg) => {
10001003
this.sendErrorResponse(response, 6, `Could not restart: ${msg}`);
10011004
});
@@ -1176,13 +1179,16 @@ export class GDBDebugSession extends DebugSession {
11761179
}
11771180

11781181
protected stopEvent(info: MINode, reason: string = 'exception') {
1179-
if (!this.started) { this.crashed = true; }
11801182
if (!this.quit) {
11811183
this.stopped = true;
11821184
this.stoppedReason = reason;
11831185
this.findPausedThread(info);
1184-
this.sendEvent(new StoppedEvent(reason, this.currentThreadId, true));
1185-
this.sendEvent(new CustomStoppedEvent(reason, this.currentThreadId));
1186+
if ((reason === 'entry') && this.args.noDebug) {
1187+
// Do not notify the front-end if no-debug is active and it is the entry point. Or else, pass it on
1188+
} else {
1189+
this.sendEvent(new StoppedEvent(reason, this.currentThreadId, true));
1190+
this.sendEvent(new CustomStoppedEvent(reason, this.currentThreadId));
1191+
}
11861192
}
11871193
}
11881194

0 commit comments

Comments
 (0)