Skip to content

Commit b024151

Browse files
thorstendb-ARMomarArm
authored andcommitted
GDB: allow access while CPU is running (code refactor) (eclipse-cdt-cloud#383)
* GDB: allow access while CPU is running Cannot use GDB CLI commands while CPU is running eclipse-cdt-cloud#82
1 parent f803117 commit b024151

File tree

8 files changed

+146
-143
lines changed

8 files changed

+146
-143
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log
22

3+
## Unreleased
4+
5+
- Refactor [#362](https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/362): Cannot execute CLI commands like > interrupt from Debug Console while CPU is running
6+
37
## 1.0.9
48

59
- Implements [#360](https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/360): Support GDB/MI breakpoint notifications.

src/gdb/GDBDebugSessionBase.ts

Lines changed: 70 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,10 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
967967
args: DebugProtocol.StepOutArguments
968968
): Promise<void> {
969969
try {
970-
await mi.sendExecFinish(this.gdb, args.threadId, 0);
970+
await mi.sendExecFinish(this.gdb, {
971+
threadId: args.threadId,
972+
frameId: 0,
973+
});
971974
this.sendResponse(response);
972975
} catch (err) {
973976
this.sendErrorResponse(
@@ -1023,7 +1026,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
10231026
response: DebugProtocol.ScopesResponse,
10241027
args: DebugProtocol.ScopesArguments
10251028
): void {
1026-
const frame: FrameVariableReference = {
1029+
const frameVarRef: FrameVariableReference = {
10271030
type: 'frame',
10281031
frameHandle: args.frameId,
10291032
};
@@ -1035,7 +1038,11 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
10351038

10361039
response.body = {
10371040
scopes: [
1038-
new Scope('Local', this.variableHandles.create(frame), false),
1041+
new Scope(
1042+
'Local',
1043+
this.variableHandles.create(frameVarRef),
1044+
false
1045+
),
10391046
new Scope(
10401047
'Registers',
10411048
this.variableHandles.create(registers),
@@ -1092,8 +1099,8 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
10921099
this.sendResponse(response);
10931100
return;
10941101
}
1095-
const frame = this.frameHandles.get(ref.frameHandle);
1096-
if (!frame) {
1102+
const frameRef = this.frameHandles.get(ref.frameHandle);
1103+
if (!frameRef) {
10971104
this.sendResponse(response);
10981105
return;
10991106
}
@@ -1107,21 +1114,18 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
11071114
});
11081115
const depth = parseInt(stackDepth.depth, 10);
11091116
let varobj = this.gdb.varManager.getVar(
1110-
frame.frameId,
1111-
frame.threadId,
1117+
frameRef,
11121118
depth,
11131119
varname,
11141120
ref.type
11151121
);
11161122
if (!varobj && ref.type === 'registers') {
11171123
const varCreateResponse = await mi.sendVarCreate(this.gdb, {
11181124
expression: '$' + args.name,
1119-
frameId: frame.frameId,
1120-
threadId: frame.threadId,
1125+
frameRef,
11211126
});
11221127
varobj = this.gdb.varManager.addVar(
1123-
frame.frameId,
1124-
frame.threadId,
1128+
frameRef,
11251129
depth,
11261130
args.name,
11271131
false,
@@ -1158,8 +1162,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
11581162
'.' +
11591163
args.name.replace(/^\[(\d+)\]/, '$1');
11601164
varobj = this.gdb.varManager.getVar(
1161-
frame.frameId,
1162-
frame.threadId,
1165+
frameRef,
11631166
depth,
11641167
grandchildVarname
11651168
);
@@ -1207,6 +1210,27 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
12071210
// this.sendResponse(response);
12081211
// }
12091212

1213+
protected async evaluateRequestGdbCommand(
1214+
response: DebugProtocol.EvaluateResponse,
1215+
args: DebugProtocol.EvaluateArguments,
1216+
frameRef: FrameReference | undefined
1217+
): Promise<void> {
1218+
if (args.expression[1] === '-') {
1219+
await this.gdb.sendCommand(args.expression.slice(1));
1220+
} else {
1221+
await mi.sendInterpreterExecConsole(this.gdb, {
1222+
frameRef,
1223+
command: args.expression.slice(1),
1224+
});
1225+
}
1226+
response.body = {
1227+
result: '\r',
1228+
variablesReference: 0,
1229+
};
1230+
this.sendResponse(response);
1231+
return;
1232+
}
1233+
12101234
protected async evaluateRequest(
12111235
response: DebugProtocol.EvaluateResponse,
12121236
args: DebugProtocol.EvaluateArguments
@@ -1222,49 +1246,39 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
12221246
);
12231247
}
12241248

1225-
const frame = this.frameHandles.get(args.frameId);
1226-
if (!frame) {
1249+
const frameRef = args.frameId
1250+
? this.frameHandles.get(args.frameId)
1251+
: undefined;
1252+
1253+
if (!frameRef) {
12271254
this.sendResponse(response);
12281255
return;
12291256
}
12301257

12311258
if (args.expression.startsWith('>') && args.context === 'repl') {
1232-
if (args.expression[1] === '-') {
1233-
await this.gdb.sendCommand(args.expression.slice(1));
1234-
} else {
1235-
await mi.sendInterpreterExecConsole(this.gdb, {
1236-
threadId: frame.threadId,
1237-
frameId: frame.frameId,
1238-
command: args.expression.slice(1),
1239-
});
1240-
}
1241-
response.body = {
1242-
result: '\r',
1243-
variablesReference: 0,
1244-
};
1245-
this.sendResponse(response);
1246-
return;
1259+
return await this.evaluateRequestGdbCommand(
1260+
response,
1261+
args,
1262+
frameRef
1263+
);
12471264
}
12481265

12491266
const stackDepth = await mi.sendStackInfoDepth(this.gdb, {
12501267
maxDepth: 100,
12511268
});
12521269
const depth = parseInt(stackDepth.depth, 10);
12531270
let varobj = this.gdb.varManager.getVar(
1254-
frame.frameId,
1255-
frame.threadId,
1271+
frameRef,
12561272
depth,
12571273
args.expression
12581274
);
12591275
if (!varobj) {
12601276
const varCreateResponse = await mi.sendVarCreate(this.gdb, {
12611277
expression: args.expression,
1262-
frameId: frame.frameId,
1263-
threadId: frame.threadId,
1278+
frameRef,
12641279
});
12651280
varobj = this.gdb.varManager.addVar(
1266-
frame.frameId,
1267-
frame.threadId,
1281+
frameRef,
12681282
depth,
12691283
args.expression,
12701284
false,
@@ -1283,8 +1297,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
12831297
}
12841298
} else {
12851299
this.gdb.varManager.removeVar(
1286-
frame.frameId,
1287-
frame.threadId,
1300+
frameRef,
12881301
depth,
12891302
varobj.varname
12901303
);
@@ -1295,13 +1308,11 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
12951308
this.gdb,
12961309
{
12971310
expression: args.expression,
1298-
frameId: frame.frameId,
1299-
threadId: frame.threadId,
1311+
frameRef,
13001312
}
13011313
);
13021314
varobj = this.gdb.varManager.addVar(
1303-
frame.frameId,
1304-
frame.threadId,
1315+
frameRef,
13051316
depth,
13061317
args.expression,
13071318
false,
@@ -1311,7 +1322,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
13111322
}
13121323
}
13131324
}
1314-
if (varobj) {
1325+
if (varobj && args.frameId != undefined) {
13151326
const result =
13161327
args.context === 'variables' && Number(varobj.numchild)
13171328
? await this.getChildElements(varobj, args.frameId)
@@ -1870,8 +1881,8 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
18701881
): Promise<DebugProtocol.Variable[]> {
18711882
// initialize variables array and dereference the frame handle
18721883
const variables: DebugProtocol.Variable[] = [];
1873-
const frame = this.frameHandles.get(ref.frameHandle);
1874-
if (!frame) {
1884+
const frameRef = this.frameHandles.get(ref.frameHandle);
1885+
if (!frameRef) {
18751886
return Promise.resolve(variables);
18761887
}
18771888

@@ -1889,11 +1900,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
18891900
const toDelete = new Array<string>();
18901901

18911902
// get the list of vars we need to update for this frameId/threadId/depth tuple
1892-
const vars = this.gdb.varManager.getVars(
1893-
frame.frameId,
1894-
frame.threadId,
1895-
depth
1896-
);
1903+
const vars = this.gdb.varManager.getVars(frameRef, depth);
18971904
if (vars) {
18981905
for (const varobj of vars) {
18991906
// ignore expressions and child entries
@@ -1949,38 +1956,29 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
19491956
}
19501957
// clean up out of scope entries
19511958
for (const varname of toDelete) {
1952-
await this.gdb.varManager.removeVar(
1953-
frame.frameId,
1954-
frame.threadId,
1955-
depth,
1956-
varname
1957-
);
1959+
await this.gdb.varManager.removeVar(frameRef, depth, varname);
19581960
}
19591961
}
19601962
// if we had out of scope entries or no entries in the frameId/threadId/depth tuple, query GDB for new ones
19611963
if (callStack === true || numVars === 0) {
19621964
const result = await mi.sendStackListVariables(this.gdb, {
1963-
thread: frame.threadId,
1964-
frame: frame.frameId,
1965+
frameRef,
19651966
printValues: 'simple-values',
19661967
});
19671968
for (const variable of result.variables) {
19681969
let varobj = this.gdb.varManager.getVar(
1969-
frame.frameId,
1970-
frame.threadId,
1970+
frameRef,
19711971
depth,
19721972
variable.name
19731973
);
19741974
if (!varobj) {
19751975
// create var in GDB and store it in the varMgr
19761976
const varCreateResponse = await mi.sendVarCreate(this.gdb, {
19771977
expression: variable.name,
1978-
frameId: frame.frameId,
1979-
threadId: frame.threadId,
1978+
frameRef,
19801979
});
19811980
varobj = this.gdb.varManager.addVar(
1982-
frame.frameId,
1983-
frame.threadId,
1981+
frameRef,
19841982
depth,
19851983
variable.name,
19861984
true,
@@ -1990,8 +1988,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
19901988
} else {
19911989
// var existed as an expression before. Now it's a variable too.
19921990
varobj = await this.gdb.varManager.updateVar(
1993-
frame.frameId,
1994-
frame.threadId,
1991+
frameRef,
19951992
depth,
19961993
varobj
19971994
);
@@ -2027,8 +2024,8 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
20272024
): Promise<DebugProtocol.Variable[]> {
20282025
// initialize variables array and dereference the frame handle
20292026
const variables: DebugProtocol.Variable[] = [];
2030-
const frame = this.frameHandles.get(ref.frameHandle);
2031-
if (!frame) {
2027+
const frameRef = this.frameHandles.get(ref.frameHandle);
2028+
if (!frameRef) {
20322029
return Promise.resolve(variables);
20332030
}
20342031

@@ -2043,8 +2040,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
20432040

20442041
// if a varobj exists, use the varname stored there
20452042
const varobj = this.gdb.varManager.getVarByName(
2046-
frame.frameId,
2047-
frame.threadId,
2043+
frameRef,
20482044
depth,
20492045
ref.varobjName
20502046
);
@@ -2153,15 +2149,14 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
21532149
): Promise<DebugProtocol.Variable[]> {
21542150
// initialize variables array and dereference the frame handle
21552151
const variables: DebugProtocol.Variable[] = [];
2156-
const frame = this.frameHandles.get(ref.frameHandle);
2157-
if (!frame) {
2152+
const frameRef = this.frameHandles.get(ref.frameHandle);
2153+
if (!frameRef) {
21582154
return Promise.resolve(variables);
21592155
}
21602156

21612157
if (this.registerMap.size === 0) {
21622158
const result_names = await mi.sendDataListRegisterNames(this.gdb, {
2163-
frameId: frame.frameId,
2164-
threadId: frame.threadId,
2159+
frameRef,
21652160
});
21662161
let idx = 0;
21672162
const registerNames = result_names['register-names'];
@@ -2176,8 +2171,7 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
21762171

21772172
const result_values = await mi.sendDataListRegisterValues(this.gdb, {
21782173
fmt: 'x',
2179-
frameId: frame.frameId,
2180-
threadId: frame.threadId,
2174+
frameRef,
21812175
});
21822176
const reg_values = result_values['register-values'];
21832177
for (const n of reg_values) {

src/mi/data.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*********************************************************************/
1010

1111
import { IGDBBackend } from '../types/gdb';
12+
import { FrameReference } from '../types/session';
1213
import { MIResponse, MIRegisterValueInfo } from './base';
1314

1415
interface MIDataReadMemoryBytesResponse {
@@ -123,11 +124,10 @@ export function sendDataListRegisterNames(
123124
gdb: IGDBBackend,
124125
params: {
125126
regno?: number[];
126-
frameId: number;
127-
threadId: number;
127+
frameRef: FrameReference;
128128
}
129129
): Promise<MIListRegisterNamesResponse> {
130-
let command = `-data-list-register-names --frame ${params.frameId} --thread ${params.threadId}`;
130+
let command = `-data-list-register-names --frame ${params.frameRef.frameId} --thread ${params.frameRef.threadId}`;
131131

132132
if (params.regno) {
133133
command += params.regno.join(' ');
@@ -141,11 +141,10 @@ export function sendDataListRegisterValues(
141141
params: {
142142
fmt: string;
143143
regno?: number[];
144-
frameId: number;
145-
threadId: number;
144+
frameRef: FrameReference;
146145
}
147146
): Promise<MIListRegisterValuesResponse> {
148-
let command = `-data-list-register-values --frame ${params.frameId} --thread ${params.threadId} ${params.fmt}`;
147+
let command = `-data-list-register-values --frame ${params.frameRef.frameId} --thread ${params.frameRef.threadId} ${params.fmt}`;
149148

150149
if (params.regno) {
151150
command += params.regno.join(' ');

0 commit comments

Comments
 (0)