Skip to content

Commit c028fd8

Browse files
nomtatsWebFreak001
authored andcommitted
Add support to retrieve register values.
1 parent 7ee97b6 commit c028fd8

File tree

3 files changed

+122
-55
lines changed

3 files changed

+122
-55
lines changed

src/backend/backend.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export interface Variable {
3333
raw?: any;
3434
}
3535

36+
export interface RegisterValue {
37+
index: number;
38+
value: string;
39+
}
40+
3641
export interface SSHArguments {
3742
forwardX11: boolean;
3843
host: string;

src/backend/mi2/mi2.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Breakpoint, IBackend, Thread, Stack, SSHArguments, Variable, VariableObject, MIError } from "../backend";
1+
import { Breakpoint, IBackend, Thread, Stack, SSHArguments, Variable, RegisterValue, VariableObject, MIError } from "../backend";
22
import * as ChildProcess from "child_process";
33
import { EventEmitter } from "events";
44
import { parseMI, MINode } from '../mi_parse';
@@ -758,6 +758,57 @@ export class MI2 extends EventEmitter implements IBackend {
758758
return ret;
759759
}
760760

761+
async getRegisters(): Promise<Variable[]> {
762+
if (trace)
763+
this.log("stderr", "getRegisters");
764+
765+
// Getting register names and values are separate GDB commands.
766+
// We first retrieve the register names and then the values.
767+
// The register names should never change, so we could cache and reuse them,
768+
// but for now we just retrieve them every time to keep it simple.
769+
const names = await this.getRegisterNames();
770+
const values = await this.getRegisterValues();
771+
const ret: Variable[] = [];
772+
for (const val of values) {
773+
const key = names[val.index];
774+
const value = val.value;
775+
const type = "string";
776+
ret.push({
777+
name: key,
778+
valueStr: value,
779+
type: type
780+
});
781+
}
782+
return ret;
783+
}
784+
785+
async getRegisterNames(): Promise<string[]> {
786+
if (trace)
787+
this.log("stderr", "getRegisterNames");
788+
const result = await this.sendCommand("data-list-register-names");
789+
const names = result.result('register-names');
790+
if (!Array.isArray(names)) {
791+
throw new Error('Failed to retrieve register names.');
792+
}
793+
return names.map(name => name.toString());
794+
}
795+
796+
async getRegisterValues(): Promise<RegisterValue[]> {
797+
if (trace)
798+
this.log("stderr", "getRegisterValues");
799+
const result = await this.sendCommand("data-list-register-values N");
800+
const nodes = result.result('register-values');
801+
if (!Array.isArray(nodes)) {
802+
throw new Error('Failed to retrieve register values.');
803+
}
804+
const ret: RegisterValue[] = nodes.map(node => {
805+
const index = parseInt(MINode.valueOf(node, "number"));
806+
const value = MINode.valueOf(node, "value");
807+
return {index: index, value: value};
808+
});
809+
return ret;
810+
}
811+
761812
examineMemory(from: number, length: number): Thenable<any> {
762813
if (trace)
763814
this.log("stderr", "examineMemory");

src/mibase.ts

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,8 @@ export class MI2DebugSession extends DebugSession {
405405
return new Scope(scopeName, handle, expensive);
406406
};
407407

408-
scopes.push(createScope("Local", false));
408+
scopes.push(createScope("Registers", false));
409+
scopes.push(createScope("Locals", false));
409410

410411
response.body = {
411412
scopes: scopes
@@ -436,64 +437,74 @@ export class MI2DebugSession extends DebugSession {
436437
};
437438

438439
if (id instanceof VariableScope) {
439-
let stack: Variable[];
440440
try {
441-
stack = await this.miDebugger.getStackVariables(id.threadId, id.level);
442-
for (const variable of stack) {
443-
if (this.useVarObjects) {
444-
try {
445-
const varObjName = VariableScope.variableName(args.variablesReference, variable.name);
446-
let varObj: VariableObject;
441+
if (id.name == "Registers") {
442+
const registers = await this.miDebugger.getRegisters();
443+
for (const reg of registers) {
444+
variables.push({
445+
name: reg.name,
446+
value: reg.valueStr,
447+
variablesReference: 0
448+
});
449+
}
450+
} else {
451+
const stack: Variable[] = await this.miDebugger.getStackVariables(id.threadId, id.level);
452+
for (const variable of stack) {
453+
if (this.useVarObjects) {
447454
try {
448-
const changes = await this.miDebugger.varUpdate(varObjName);
449-
const changelist = changes.result("changelist");
450-
changelist.forEach((change) => {
451-
const name = MINode.valueOf(change, "name");
452-
const vId = this.variableHandlesReverse[name];
453-
const v = this.variableHandles.get(vId) as any;
454-
v.applyChanges(change);
455-
});
456-
const varId = this.variableHandlesReverse[varObjName];
457-
varObj = this.variableHandles.get(varId) as any;
458-
} catch (err) {
459-
if (err instanceof MIError && err.message == "Variable object not found") {
460-
varObj = await this.miDebugger.varCreate(variable.name, varObjName);
461-
const varId = findOrCreateVariable(varObj);
462-
varObj.exp = variable.name;
463-
varObj.id = varId;
464-
} else {
465-
throw err;
455+
const varObjName = VariableScope.variableName(args.variablesReference, variable.name);
456+
let varObj: VariableObject;
457+
try {
458+
const changes = await this.miDebugger.varUpdate(varObjName);
459+
const changelist = changes.result("changelist");
460+
changelist.forEach((change) => {
461+
const name = MINode.valueOf(change, "name");
462+
const vId = this.variableHandlesReverse[name];
463+
const v = this.variableHandles.get(vId) as any;
464+
v.applyChanges(change);
465+
});
466+
const varId = this.variableHandlesReverse[varObjName];
467+
varObj = this.variableHandles.get(varId) as any;
468+
} catch (err) {
469+
if (err instanceof MIError && err.message == "Variable object not found") {
470+
varObj = await this.miDebugger.varCreate(variable.name, varObjName);
471+
const varId = findOrCreateVariable(varObj);
472+
varObj.exp = variable.name;
473+
varObj.id = varId;
474+
} else {
475+
throw err;
476+
}
466477
}
478+
variables.push(varObj.toProtocolVariable());
479+
} catch (err) {
480+
variables.push({
481+
name: variable.name,
482+
value: `<${err}>`,
483+
variablesReference: 0
484+
});
467485
}
468-
variables.push(varObj.toProtocolVariable());
469-
} catch (err) {
470-
variables.push({
471-
name: variable.name,
472-
value: `<${err}>`,
473-
variablesReference: 0
474-
});
486+
} else {
487+
if (variable.valueStr !== undefined) {
488+
let expanded = expandValue(createVariable, `{${variable.name}=${variable.valueStr})`, "", variable.raw);
489+
if (expanded) {
490+
if (typeof expanded[0] == "string")
491+
expanded = [
492+
{
493+
name: "<value>",
494+
value: prettyStringArray(expanded),
495+
variablesReference: 0
496+
}
497+
];
498+
variables.push(expanded[0]);
499+
}
500+
} else
501+
variables.push({
502+
name: variable.name,
503+
type: variable.type,
504+
value: "<unknown>",
505+
variablesReference: createVariable(variable.name)
506+
});
475507
}
476-
} else {
477-
if (variable.valueStr !== undefined) {
478-
let expanded = expandValue(createVariable, `{${variable.name}=${variable.valueStr})`, "", variable.raw);
479-
if (expanded) {
480-
if (typeof expanded[0] == "string")
481-
expanded = [
482-
{
483-
name: "<value>",
484-
value: prettyStringArray(expanded),
485-
variablesReference: 0
486-
}
487-
];
488-
variables.push(expanded[0]);
489-
}
490-
} else
491-
variables.push({
492-
name: variable.name,
493-
type: variable.type,
494-
value: "<unknown>",
495-
variablesReference: createVariable(variable.name)
496-
});
497508
}
498509
}
499510
response.body = {

0 commit comments

Comments
 (0)