Skip to content

Commit

Permalink
extend setVariableRequest to allow editing registers (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
QuocDoBV authored Sep 12, 2022
1 parent 3ea8dad commit 95d05ed
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 6 deletions.
21 changes: 20 additions & 1 deletion src/GDBDebugSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -987,8 +987,27 @@ export class GDBDebugSession extends LoggingDebugSession {
frame.frameId,
frame.threadId,
depth,
varname
varname,
ref.type
);
if (!varobj && ref.type === 'registers') {
const varCreateResponse = await mi.sendVarCreate(this.gdb, {
expression: '$' + args.name,
frameId: frame.frameId,
threadId: frame.threadId,
});
varobj = this.gdb.varManager.addVar(
frame.frameId,
frame.threadId,
depth,
args.name,
false,
false,
varCreateResponse,
ref.type
);
await mi.sendVarSetFormatToHex(this.gdb, varobj.varname);
}
let assign;
if (varobj) {
assign = await mi.sendVarAssign(this.gdb, {
Expand Down
1 change: 1 addition & 0 deletions src/integration-tests/test-programs/vars.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ int main()
int e = r.z.a + r.z.b;
int f[] = {1, 2, 3};
int g = f[0] + f[1] + f[2]; // After array init
int rax = 1;
return 0;
}
19 changes: 19 additions & 0 deletions src/integration-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ export function verifyVariable(
}
}

/**
* Test a given register variable returned from a variablesRequest against an expected name and/or value.
*/
export function verifyRegister(
variable: DebugProtocol.Variable,
expectedName: string,
expectedValue?: string
) {
expect(variable.name, `The name of ${expectedName} is wrong`).to.equal(
expectedName
);
if (expectedValue) {
expect(
variable.value,
`The value of ${expectedName} is wrong`
).to.equal(expectedValue);
}
}

export function compareVariable(
varA: DebugProtocol.Variable,
varB: DebugProtocol.Variable,
Expand Down
47 changes: 45 additions & 2 deletions src/integration-tests/var.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
standardBeforeEach,
testProgramsDir,
verifyVariable,
verifyRegister,
} from './utils';
import * as chai from 'chai';
import * as chaistring from 'chai-string';
Expand All @@ -33,7 +34,7 @@ describe('Variables Test Suite', function () {
let scope: Scope;
const varsProgram = path.join(testProgramsDir, 'vars');
const varsSrc = path.join(testProgramsDir, 'vars.c');
const numVars = 8; // number of variables in the main() scope of vars.c
const numVars = 9; // number of variables in the main() scope of vars.c

const lineTags = {
'STOP HERE': 0,
Expand Down Expand Up @@ -134,10 +135,13 @@ describe('Variables Test Suite', function () {
verifyVariable(vars.body.variables[2], 'c', 'int', '35');
});

it('can read registers in a program', async function () {
it('can read and set simple registers in a program', async function () {
// read the registers
const vr = scope.scopes.body.scopes[1].variablesReference;
const vr1 = scope.scopes.body.scopes[0].variablesReference;
const vars = await dc.variablesRequest({ variablesReference: vr });
const vars1 = await dc.variablesRequest({ variablesReference: vr1 });

expect(
vars.body.variables.length,
'There is a different number of variables than expected'
Expand All @@ -151,6 +155,45 @@ describe('Variables Test Suite', function () {
expect(r0.name).to.not.equal(r1.name);
// add other useful tests here, especially ones that test boundary conditions
expect(rn?.evaluateName).to.startWith('$'); // check last registers
// set the registers value to something different
const setR0 = await dc.setVariableRequest({
name: r0.name,
value: '55',
variablesReference: vr,
});
expect(setR0.body.value).to.equal('0x37');
const setR0inHex = await dc.setVariableRequest({
name: r0.name,
value: '0x55',
variablesReference: vr,
});
expect(setR0inHex.body.value).to.equal('0x55');
const setR1inHex = await dc.setVariableRequest({
name: r1.name,
value: '0x45',
variablesReference: vr,
});
expect(setR1inHex.body.value).to.equal('0x45');
const setR1 = await dc.setVariableRequest({
name: r1.name,
value: '45',
variablesReference: vr,
});
expect(setR1.body.value).to.equal('0x2d');
// assert that the registers value have been updated to the new values
const vars2 = await dc.variablesRequest({ variablesReference: vr });
const vars3 = await dc.variablesRequest({ variablesReference: vr1 });
expect(
vars2.body.variables.length,
'There is a different number of registers than expected'
).to.equal(vars.body.variables.length);
verifyRegister(vars2.body.variables[0], r0.name, '0x55');
verifyRegister(vars2.body.variables[1], r1.name, '0x2d');
verifyRegister(
vars3.body.variables[8],
r0.name,
vars1.body.variables[8].value
);
});

it('can read and set struct variables in a program', async function () {
Expand Down
8 changes: 8 additions & 0 deletions src/mi/var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,11 @@ export function sendVarInfoPathExpression(
const command = `-var-info-path-expression ${name}`;
return gdb.sendCommand(command);
}

export function sendVarSetFormatToHex(
gdb: GDBBackend,
name: string
): Promise<void> {
const command = `-var-set-format ${name} hexadecimal`;
return gdb.sendCommand(command);
}
15 changes: 12 additions & 3 deletions src/varManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface VarObjType {
type: string;
isVar: boolean;
isChild: boolean;
varType: string;
}

export class VarManager {
Expand Down Expand Up @@ -39,13 +40,19 @@ export class VarManager {
frameId: number,
threadId: number,
depth: number,
expression: string
expression: string,
type?: string
): VarObjType | undefined {
const vars = this.getVars(frameId, threadId, depth);
if (vars) {
for (const varobj of vars) {
if (varobj.expression === expression) {
return varobj;
if (type !== 'registers') {
type = 'local';
}
if (type === varobj.varType) {
return varobj;
}
}
}
}
Expand Down Expand Up @@ -76,7 +83,8 @@ export class VarManager {
expression: string,
isVar: boolean,
isChild: boolean,
varCreateResponse: MIVarCreateResponse
varCreateResponse: MIVarCreateResponse,
type?: string
): VarObjType {
let vars = this.variableMap.get(this.getKey(frameId, threadId, depth));
if (!vars) {
Expand All @@ -92,6 +100,7 @@ export class VarManager {
type: varCreateResponse.type,
isVar,
isChild,
varType: type ? type : 'local',
};
vars.push(varobj);
return varobj;
Expand Down

0 comments on commit 95d05ed

Please sign in to comment.