Skip to content

Commit 7aec463

Browse files
author
WebFreak001
committed
Merge branch 'master' of github.com:WebFreak001/code-debug
2 parents 69679be + 73473e1 commit 7aec463

File tree

7 files changed

+402
-118
lines changed

7 files changed

+402
-118
lines changed

package.json

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@
101101
"description": "Additional arguments to pass to GDB",
102102
"default": []
103103
},
104+
"valuesFormatting": {
105+
"type": "string",
106+
"description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any",
107+
"default": "parseText",
108+
"enum": [
109+
"disabled",
110+
"parseText",
111+
"prettyPrinters"
112+
]
113+
},
104114
"printCalls": {
105115
"type": "boolean",
106116
"description": "Prints all GDB calls to the console",
@@ -192,6 +202,16 @@
192202
"description": "If true this will connect to a gdbserver instead of attaching to a PID",
193203
"default": false
194204
},
205+
"valuesFormatting": {
206+
"type": "string",
207+
"description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any",
208+
"default": "parseText",
209+
"enum": [
210+
"disabled",
211+
"parseText",
212+
"prettyPrinters"
213+
]
214+
},
195215
"printCalls": {
196216
"type": "boolean",
197217
"description": "Prints all GDB calls to the console",
@@ -466,6 +486,16 @@
466486
"description": "Additional arguments to pass to LLDB",
467487
"default": []
468488
},
489+
"valuesFormatting": {
490+
"type": "string",
491+
"description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any",
492+
"default": "parseText",
493+
"enum": [
494+
"disabled",
495+
"parseText",
496+
"prettyPrinters"
497+
]
498+
},
469499
"printCalls": {
470500
"type": "boolean",
471501
"description": "Prints all lldb calls to the console",
@@ -552,6 +582,16 @@
552582
"type": "string",
553583
"description": "PID of running program or program name"
554584
},
585+
"valuesFormatting": {
586+
"type": "string",
587+
"description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any",
588+
"default": "parseText",
589+
"enum": [
590+
"disabled",
591+
"parseText",
592+
"prettyPrinters"
593+
]
594+
},
555595
"printCalls": {
556596
"type": "boolean",
557597
"description": "Prints all LLDB calls to the console",
@@ -713,6 +753,16 @@
713753
"description": "Additional arguments to pass to mago",
714754
"default": []
715755
},
756+
"valuesFormatting": {
757+
"type": "string",
758+
"description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any",
759+
"default": "parseText",
760+
"enum": [
761+
"disabled",
762+
"parseText",
763+
"prettyPrinters"
764+
]
765+
},
716766
"printCalls": {
717767
"type": "boolean",
718768
"description": "Prints all mago calls to the console",
@@ -739,6 +789,16 @@
739789
"type": "string",
740790
"description": "PID of running program or program name"
741791
},
792+
"valuesFormatting": {
793+
"type": "string",
794+
"description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any",
795+
"default": "parseText",
796+
"enum": [
797+
"disabled",
798+
"parseText",
799+
"prettyPrinters"
800+
]
801+
},
742802
"printCalls": {
743803
"type": "boolean",
744804
"description": "Prints all mago calls to the console",
@@ -834,4 +894,4 @@
834894
"@types/node": "^7.0.5",
835895
"@types/mocha": "^2.2.39"
836896
}
837-
}
897+
}

src/backend/backend.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import { MINode } from "./mi_parse";
2+
import { DebugProtocol } from "vscode-debugprotocol/lib/debugProtocol";
3+
4+
export type ValuesFormattingMode = "disabled" | "parseText" | "prettyPrinters";
5+
16
export interface Breakpoint {
27
file?: string;
38
line?: number;
@@ -59,4 +64,62 @@ export interface IBackend {
5964
isReady(): boolean;
6065
changeVariable(name: string, rawValue: string): Thenable<any>;
6166
examineMemory(from: number, to: number): Thenable<any>;
62-
}
67+
}
68+
69+
export class VariableObject {
70+
name: string;
71+
exp: string;
72+
numchild: number;
73+
type: string;
74+
value: string;
75+
threadId: string;
76+
frozen: boolean;
77+
dynamic: boolean;
78+
displayhint: string;
79+
has_more: boolean;
80+
id: number;
81+
constructor(node: any) {
82+
this.name = MINode.valueOf(node, "name");
83+
this.exp = MINode.valueOf(node, "exp");
84+
this.numchild = parseInt(MINode.valueOf(node, "numchild"));
85+
this.type = MINode.valueOf(node, "type");
86+
this.value = MINode.valueOf(node, "value");
87+
this.threadId = MINode.valueOf(node, "thread-id");
88+
this.frozen = !!MINode.valueOf(node, "frozen");
89+
this.dynamic = !!MINode.valueOf(node, "dynamic");
90+
this.displayhint = MINode.valueOf(node, "displayhint");
91+
// TODO: use has_more when it's > 0
92+
this.has_more = !!MINode.valueOf(node, "has_more");
93+
}
94+
95+
public applyChanges(node: MINode) {
96+
this.value = MINode.valueOf(node, "value");
97+
if (!!MINode.valueOf(node, "type_changed")) {
98+
this.type = MINode.valueOf(node, "new_type");
99+
}
100+
this.dynamic = !!MINode.valueOf(node, "dynamic");
101+
this.displayhint = MINode.valueOf(node, "displayhint");
102+
this.has_more = !!MINode.valueOf(node, "has_more");
103+
}
104+
105+
public isCompound(): boolean {
106+
return this.numchild > 0 ||
107+
this.value === "{...}" ||
108+
(this.dynamic && (this.displayhint === "array" || this.displayhint === "map"));
109+
}
110+
111+
public toProtocolVariable(): DebugProtocol.Variable {
112+
let res: DebugProtocol.Variable = {
113+
name: this.exp,
114+
evaluateName: this.name,
115+
value: (this.value === void 0) ? "<unknown>" : this.value,
116+
type: this.type,
117+
// kind: this.displayhint,
118+
variablesReference: this.id
119+
};
120+
if (this.displayhint) {
121+
res.kind = this.displayhint;
122+
}
123+
return res;
124+
}
125+
}

src/backend/mi2/mi2.ts

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Breakpoint, IBackend, Stack, SSHArguments, Variable } from "../backend"
1+
import { Breakpoint, IBackend, Stack, SSHArguments, Variable, VariableObject } from "../backend"
22
import * as ChildProcess from "child_process"
33
import { EventEmitter } from "events"
44
import { parseMI, MINode } from '../mi_parse';
@@ -196,6 +196,9 @@ export class MI2 extends EventEmitter implements IBackend {
196196
];
197197
if (!attach)
198198
cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\""));
199+
if (this.prettyPrint)
200+
cmds.push(this.sendCommand("enable-pretty-printing"));
201+
199202
return cmds;
200203
}
201204

@@ -617,27 +620,25 @@ export class MI2 extends EventEmitter implements IBackend {
617620
});
618621
}
619622

620-
getStackVariables(thread: number, frame: number): Thenable<Variable[]> {
623+
async getStackVariables(thread: number, frame: number): Promise<Variable[]> {
621624
if (trace)
622625
this.log("stderr", "getStackVariables");
623-
return new Promise((resolve, reject) => {
624-
this.sendCommand("stack-list-variables --thread " + thread + " --frame " + frame + " --simple-values").then((result) => {
625-
let variables = result.result("variables");
626-
let ret: Variable[] = [];
627-
variables.forEach(element => {
628-
const key = MINode.valueOf(element, "name");
629-
const value = MINode.valueOf(element, "value");
630-
const type = MINode.valueOf(element, "type");
631-
ret.push({
632-
name: key,
633-
valueStr: value,
634-
type: type,
635-
raw: element
636-
});
637-
});
638-
resolve(ret);
639-
}, reject);
640-
});
626+
627+
const result = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --simple-values`);
628+
const variables = result.result("variables");
629+
let ret: Variable[] = [];
630+
for (const element of variables) {
631+
const key = MINode.valueOf(element, "name");
632+
const value = MINode.valueOf(element, "value");
633+
const type = MINode.valueOf(element, "type");
634+
ret.push({
635+
name: key,
636+
valueStr: value,
637+
type: type,
638+
raw: element
639+
});
640+
}
641+
return ret;
641642
}
642643

643644
examineMemory(from: number, length: number): Thenable<any> {
@@ -660,6 +661,41 @@ export class MI2 extends EventEmitter implements IBackend {
660661
});
661662
}
662663

664+
async varCreate(expression: string, name: string = "-"): Promise<VariableObject> {
665+
if (trace)
666+
this.log("stderr", "varCreate");
667+
const res = await this.sendCommand(`var-create ${name} @ "${expression}"`);
668+
return new VariableObject(res.result(""));
669+
}
670+
671+
async varEvalExpression(name: string): Promise<MINode> {
672+
if (trace)
673+
this.log("stderr", "varEvalExpression");
674+
return this.sendCommand(`var-evaluate-expression ${name}`);
675+
}
676+
677+
async varListChildren(name: string): Promise<VariableObject[]> {
678+
if (trace)
679+
this.log("stderr", "varListChildren");
680+
//TODO: add `from` and `to` arguments
681+
const res = await this.sendCommand(`var-list-children --all-values ${name}`);
682+
const children = res.result("children");
683+
let omg: VariableObject[] = children.map(child => new VariableObject(child[1]));
684+
return omg;
685+
}
686+
687+
async varUpdate(name: string = "*"): Promise<MINode> {
688+
if (trace)
689+
this.log("stderr", "varUpdate");
690+
return this.sendCommand(`var-update --all-values ${name}`)
691+
}
692+
693+
async varAssign(name: string, rawValue: string): Promise<MINode> {
694+
if (trace)
695+
this.log("stderr", "varAssign");
696+
return this.sendCommand(`var-assign ${name} ${rawValue}`);
697+
}
698+
663699
logNoNewLine(type: string, msg: string) {
664700
this.emit("msg", type, msg);
665701
}
@@ -710,6 +746,7 @@ export class MI2 extends EventEmitter implements IBackend {
710746
return this.isSSH ? this.sshReady : !!this.process;
711747
}
712748

749+
prettyPrint: boolean = true;
713750
printCalls: boolean;
714751
debugOutput: boolean;
715752
public procEnv: any;

src/gdb.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { MI2DebugSession } from './mibase';
22
import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from 'vscode-debugadapter';
33
import { DebugProtocol } from 'vscode-debugprotocol';
44
import { MI2 } from "./backend/mi2/mi2";
5-
import { SSHArguments } from './backend/backend';
5+
import { SSHArguments, ValuesFormattingMode } from './backend/backend';
66

77
export interface LaunchRequestArguments {
88
cwd: string;
@@ -14,6 +14,7 @@ export interface LaunchRequestArguments {
1414
terminal: string;
1515
autorun: string[];
1616
ssh: SSHArguments;
17+
valuesFormatting: ValuesFormattingMode;
1718
printCalls: boolean;
1819
showDevDebugOutput: boolean;
1920
}
@@ -28,6 +29,7 @@ export interface AttachRequestArguments {
2829
remote: boolean;
2930
autorun: string[];
3031
ssh: SSHArguments;
32+
valuesFormatting: ValuesFormattingMode;
3133
printCalls: boolean;
3234
showDevDebugOutput: boolean;
3335
}
@@ -54,6 +56,7 @@ class GDBDebugSession extends MI2DebugSession {
5456
this.started = false;
5557
this.crashed = false;
5658
this.debugReady = false;
59+
this.setValuesFormattingMode(args.valuesFormatting);
5760
this.miDebugger.printCalls = !!args.printCalls;
5861
this.miDebugger.debugOutput = !!args.showDevDebugOutput;
5962
if (args.ssh !== undefined) {
@@ -121,6 +124,7 @@ class GDBDebugSession extends MI2DebugSession {
121124
this.needContinue = true;
122125
this.isSSH = false;
123126
this.debugReady = false;
127+
this.setValuesFormattingMode(args.valuesFormatting);
124128
this.miDebugger.printCalls = !!args.printCalls;
125129
this.miDebugger.debugOutput = !!args.showDevDebugOutput;
126130
if (args.ssh !== undefined) {
@@ -177,4 +181,4 @@ class GDBDebugSession extends MI2DebugSession {
177181
}
178182
}
179183

180-
DebugSession.run(GDBDebugSession);
184+
DebugSession.run(GDBDebugSession);

src/lldb.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { MI2DebugSession } from './mibase';
22
import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from 'vscode-debugadapter';
33
import { DebugProtocol } from 'vscode-debugprotocol';
44
import { MI2_LLDB } from "./backend/mi2/mi2lldb";
5-
import { SSHArguments } from './backend/backend';
5+
import { SSHArguments, ValuesFormattingMode } from './backend/backend';
66

77
export interface LaunchRequestArguments {
88
cwd: string;
@@ -13,6 +13,7 @@ export interface LaunchRequestArguments {
1313
arguments: string;
1414
autorun: string[];
1515
ssh: SSHArguments;
16+
valuesFormatting: ValuesFormattingMode;
1617
printCalls: boolean;
1718
showDevDebugOutput: boolean;
1819
}
@@ -25,6 +26,7 @@ export interface AttachRequestArguments {
2526
debugger_args: string[];
2627
executable: string;
2728
autorun: string[];
29+
valuesFormatting: ValuesFormattingMode;
2830
printCalls: boolean;
2931
showDevDebugOutput: boolean;
3032
}
@@ -49,6 +51,7 @@ class LLDBDebugSession extends MI2DebugSession {
4951
this.started = false;
5052
this.crashed = false;
5153
this.debugReady = false;
54+
this.setValuesFormattingMode(args.valuesFormatting);
5255
this.miDebugger.printCalls = !!args.printCalls;
5356
this.miDebugger.debugOutput = !!args.showDevDebugOutput;
5457
if (args.ssh !== undefined) {
@@ -108,6 +111,7 @@ class LLDBDebugSession extends MI2DebugSession {
108111
this.needContinue = true;
109112
this.isSSH = false;
110113
this.debugReady = false;
114+
this.setValuesFormattingMode(args.valuesFormatting);
111115
this.miDebugger.printCalls = !!args.printCalls;
112116
this.miDebugger.debugOutput = !!args.showDevDebugOutput;
113117
this.miDebugger.attach(args.cwd, args.executable, args.target).then(() => {
@@ -120,4 +124,4 @@ class LLDBDebugSession extends MI2DebugSession {
120124
}
121125
}
122126

123-
DebugSession.run(LLDBDebugSession);
127+
DebugSession.run(LLDBDebugSession);

0 commit comments

Comments
 (0)