fix: 修复无法查看指针变量的的问题

修复无法查看/设置寄存器的问题;
修复无法设置变量值的问题.

Signed-off-by: Haoyang Chen <chenhaoyang@kylinos.cn>
This commit is contained in:
Haoyang Chen 2022-10-14 14:25:29 +08:00
parent fc6a3de435
commit 65a2acc2c7
6 changed files with 141 additions and 22 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
out
node_modules
*.vsix
.vscode-test
.vscode-test
package-lock.json

72
package-lock.json generated
View File

@ -1,15 +1,18 @@
{
"name": "debug",
"version": "0.26.0",
"version": "0.26.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "debug",
"version": "0.26.0",
"version": "0.26.1",
"license": "public domain",
"dependencies": {
"json-stream-stringify": "^2.0.4",
"node-interval-tree": "^1.3.3",
"ssh2": "^1.6.0",
"stream-json": "^1.7.3",
"vscode-debugadapter": "^1.45.0",
"vscode-debugprotocol": "^1.45.0"
},
@ -719,6 +722,11 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/json-stream-stringify": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/json-stream-stringify/-/json-stream-stringify-2.0.4.tgz",
"integrity": "sha512-gIPoa6K5w6j/RnQ3fOtmvICKNJGViI83A7dnTIL+0QJ/1GKuNvCPFvbFWxt0agruF4iGgDFJvge4Gua4ZoiggQ=="
},
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@ -977,6 +985,17 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/node-interval-tree": {
"version": "1.3.3",
"resolved": "https://registry.npmmirror.com/node-interval-tree/-/node-interval-tree-1.3.3.tgz",
"integrity": "sha512-K9vk96HdTK5fEipJwxSvIIqwTqr4e3HRJeJrNxBSeVMNSC/JWARRaX7etOLOuTmrRMeOI/K5TCJu3aWIwZiNTw==",
"dependencies": {
"shallowequal": "^1.0.2"
},
"engines": {
"node": ">= 7.6.0"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -1159,6 +1178,11 @@
"randombytes": "^2.1.0"
}
},
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -1182,6 +1206,19 @@
"nan": "^2.15.0"
}
},
"node_modules/stream-chain": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/stream-chain/-/stream-chain-2.2.5.tgz",
"integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA=="
},
"node_modules/stream-json": {
"version": "1.7.4",
"resolved": "https://registry.npmmirror.com/stream-json/-/stream-json-1.7.4.tgz",
"integrity": "sha512-ja2dde1v7dOlx5/vmavn8kLrxvNfs7r2oNc5DYmNJzayDDdudyCSuTB1gFjH4XBVTIwxiMxL4i059HX+ZiouXg==",
"dependencies": {
"stream-chain": "^2.2.5"
}
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@ -2053,6 +2090,11 @@
"esprima": "^4.0.0"
}
},
"json-stream-stringify": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/json-stream-stringify/-/json-stream-stringify-2.0.4.tgz",
"integrity": "sha512-gIPoa6K5w6j/RnQ3fOtmvICKNJGViI83A7dnTIL+0QJ/1GKuNvCPFvbFWxt0agruF4iGgDFJvge4Gua4ZoiggQ=="
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@ -2243,6 +2285,14 @@
"integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
"dev": true
},
"node-interval-tree": {
"version": "1.3.3",
"resolved": "https://registry.npmmirror.com/node-interval-tree/-/node-interval-tree-1.3.3.tgz",
"integrity": "sha512-K9vk96HdTK5fEipJwxSvIIqwTqr4e3HRJeJrNxBSeVMNSC/JWARRaX7etOLOuTmrRMeOI/K5TCJu3aWIwZiNTw==",
"requires": {
"shallowequal": "^1.0.2"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -2369,6 +2419,11 @@
"randombytes": "^2.1.0"
}
},
"shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -2386,6 +2441,19 @@
"nan": "^2.15.0"
}
},
"stream-chain": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/stream-chain/-/stream-chain-2.2.5.tgz",
"integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA=="
},
"stream-json": {
"version": "1.7.4",
"resolved": "https://registry.npmmirror.com/stream-json/-/stream-json-1.7.4.tgz",
"integrity": "sha512-ja2dde1v7dOlx5/vmavn8kLrxvNfs7r2oNc5DYmNJzayDDdudyCSuTB1gFjH4XBVTIwxiMxL4i059HX+ZiouXg==",
"requires": {
"stream-chain": "^2.2.5"
}
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",

View File

@ -76,7 +76,7 @@ export interface IBackend {
getStack(startFrame: number, maxLevels: number, thread: number): Thenable<Stack[]>;
getRegisters(): Promise<any[]>;
getStackVariables(thread: number, frame: number): Thenable<Variable[]>;
evalExpression(name: string, thread: number, frame: number): Thenable<any>;
evalExpression(name: string, thread: number, frame: number, suppressFailure:boolean): Thenable<any>;
isReady(): boolean;
changeVariable(name: string, rawValue: string): Thenable<any>;
examineMemory(from: number, to: number): Thenable<any>;
@ -85,6 +85,7 @@ export interface IBackend {
export class VariableObject {
name: string;
evaluateName:string;
exp: string;
numchild: number;
type: string;
@ -97,6 +98,7 @@ export class VariableObject {
id: number;
constructor(node: any) {
this.name = MINode.valueOf(node, "name");
this.evaluateName = this.name;
this.exp = MINode.valueOf(node, "exp");
this.numchild = parseInt(MINode.valueOf(node, "numchild"));
this.type = MINode.valueOf(node, "type");

View File

@ -76,7 +76,11 @@ export function expandValue(variableCreate: Function, value: string, root: strin
}
namespace = namespace + pointerCombineChar + name;
} else
namespace = name;
if (root && root.startsWith("*"))
namespace = name.substr(1);
else {
namespace = name;
}
}
}
});
@ -211,27 +215,36 @@ export function expandValue(variableCreate: Function, value: string, root: strin
createValue = (name, val) => {
let ref = 0;
let evaluateName;
if (typeof val == "object") {
ref = variableCreate(val);
val = "Object";
} else if (typeof val == "string" && val.startsWith("*0x")) {
if (extra && MINode.valueOf(extra, "arg") == "1") {
ref = variableCreate(getNamespace("*(" + name), { arg: true });
const isVoid = MINode.valueOf(extra, "type") === "void *";
evaluateName = getNamespace( ( isVoid ? "":"*") + name);
ref = variableCreate(getNamespace( ( isVoid ? "":"*") + "(" + name), { arg: true, isVoid });
val = "<args>";
} else {
ref = variableCreate(getNamespace("*" + name));
evaluateName = getNamespace("*" + name);
ref = variableCreate(evaluateName);
val = "Object@" + val;
}
} else if (typeof val == "string" && val.startsWith("@0x")) {
ref = variableCreate(getNamespace("*&" + name.substr));
evaluateName = getNamespace("*&" + name);
ref = variableCreate(evaluateName);
val = "Ref" + val;
} else if (typeof val == "string" && val.startsWith("<...>")) {
ref = variableCreate(getNamespace(name));
evaluateName =getNamespace(name);
ref = variableCreate(evaluateName);
val = "...";
} else {
evaluateName = getNamespace(name);
}
return {
name: name,
value: val,
evaluateName,
variablesReference: ref
};
};

View File

@ -824,7 +824,7 @@ export class MI2 extends EventEmitter implements IBackend {
const type = MINode.valueOf(reg, "type");
ret.push({
name: name,
evaluateName: name,
evaluateName: '$'+name, //修复寄存器无法watch
value: value,
type: type,
variablesReference: 0
@ -895,7 +895,7 @@ export class MI2 extends EventEmitter implements IBackend {
}, reject);
});
}
async evalExpression(name: string, thread: number, frame: number): Promise<MINode> {
async evalExpression(name: string, thread: number, frame: number, suppressFailure: boolean = false): Promise<MINode> {
if (trace)
this.log("stderr", "evalExpression");
@ -908,7 +908,7 @@ export class MI2 extends EventEmitter implements IBackend {
}
command += name;
return await this.sendCommand(command);
return await this.sendCommand(command, suppressFailure);
}
async varCreate(expression: string, name: string = "-", frame: string = "@"): Promise<VariableObject> {

View File

@ -10,6 +10,7 @@ import * as systemPath from "path";
import * as net from "net";
import * as os from "os";
import * as fs from "fs";
import { hexFormat } from './backend/common';
class ExtendedVariable {
constructor(public name, public options) {
@ -193,7 +194,25 @@ export class MI2DebugSession extends DebugSession {
value: res.result("value")
};
} else {
let name = args.variablesReference == VARIABLES_TAG_REGISTER ? `$${args.name}` : args.name;
/* 字符串不修改 */
if (args.value[0] == "\"") {
this.sendErrorResponse(response, 20, "Could not modify string variable");
return;
}
let name;
let id;
if (args.variablesReference >= VAR_HANDLES_START) {
const pointerCombineChar = ".";
id = this.variableHandles.get(args.variablesReference);
if (typeof id == "string") {
name = id[0] == '*' ? id.substr(1):id + pointerCombineChar + args.name;
}
}
/* 修复寄存器无法修改 */
else if (args.variablesReference == VARIABLES_TAG_REGISTER) {
name = `$${args.name}`;
}
await this.miDebugger.changeVariable(name, args.value);
response.body = {
value: args.value
@ -459,6 +478,7 @@ export class MI2DebugSession extends DebugSession {
this.sendResponse(response);
return;
}
if (args.variablesReference < VAR_HANDLES_START) {
id = args.variablesReference - STACK_HANDLES_START;
} else {
@ -539,8 +559,9 @@ export class MI2DebugSession extends DebugSession {
} else
variables.push({
name: variable.name,
evaluateName: variable.name,
type: variable.type,
value: "<unknown>",
value: variable.type,
variablesReference: createVariable(variable.name)
});
}
@ -617,7 +638,13 @@ export class MI2DebugSession extends DebugSession {
// TODO: this evals on an (effectively) unknown thread for multithreaded programs.
const variable = await this.miDebugger.evalExpression(JSON.stringify(`${varReq.name}+${arrIndex})`), 0, 0);
try {
const expanded = expandValue(createVariable, variable.result("value"), varReq.name, variable);
let root = varReq.name;
const t = varReq.name.indexOf('(');//如果变量名称带 ( 说明它是一个参数
let name:string = varReq.name;
if (t) {
root = name.substring(0,t) + name.substring(t+1);
}
const expanded = expandValue(createVariable, variable.result("value"), root, variable);
if (!expanded) {
this.sendErrorResponse(response, 15, `Could not expand variable`);
} else {
@ -629,7 +656,7 @@ export class MI2DebugSession extends DebugSession {
return submit();
} else if (expanded[0] != '"') {
strArr.push({
name: "[err]",
name: "value",
value: expanded,
variablesReference: 0
});
@ -642,10 +669,17 @@ export class MI2DebugSession extends DebugSession {
});
addOne();
} else {
strArr.push({
name: "[err]",
value: expanded,
variablesReference: 0
expanded.forEach(element => {
let evaluateName;
if (this.variableHandlesReverse.hasOwnProperty(element.name)) {
evaluateName = this.variableHandlesReverse[element.name];
}
strArr.push({
name: element.name,
evaluateName: element.evaluateName,
value: element.value,
variablesReference: element.variablesReference
});
});
submit();
}
@ -730,10 +764,11 @@ export class MI2DebugSession extends DebugSession {
protected evaluateRequest(response: DebugProtocol.EvaluateResponse, args: DebugProtocol.EvaluateArguments): void {
const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId);
if (args.context == "watch" || args.context == "hover") {
this.miDebugger.evalExpression(args.expression, threadId, level).then((res) => {
/* 悬停查看变量时不报错 */
this.miDebugger.evalExpression(args.expression, threadId, level, args.context == "hover").then((res) => {
response.body = {
variablesReference: 0,
result: res.result("value")
result: args.expression[0] == '$' ? hexFormat(parseInt(res.result("value"))) : res.result("value")
};
this.sendResponse(response);
}, msg => {