Skip to content

Commit 2129352

Browse files
committed
Add crosgdb handler to run gdb in the choot
Signed-off-by: Sean Paul <[email protected]>
1 parent bcd9d13 commit 2129352

File tree

4 files changed

+220
-1
lines changed

4 files changed

+220
-1
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"type": "node",
2121
"request": "launch",
2222
"runtimeArgs": [ "--nolazy" ],
23-
"program": "${workspaceRoot}/src/gdb.ts",
23+
"program": "${workspaceRoot}/src/crosgdb.ts",
2424
"stopOnEntry": false,
2525
"args": [ "--server=4711" ],
2626
"sourceMaps": true,

package.json

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,134 @@
439439
}
440440
]
441441
},
442+
{
443+
"type": "crosgdb",
444+
"extensions": [],
445+
"program": "./out/src/crosgdb.js",
446+
"runtime": "node",
447+
"label": "CrOS GDB",
448+
"enableBreakpointsFor": {
449+
"languageIds": [
450+
"c",
451+
"cpp",
452+
"d",
453+
"objective-c",
454+
"fortran",
455+
"fortran-modern",
456+
"fortran90",
457+
"fortran_free-form",
458+
"fortran_fixed-form",
459+
"rust",
460+
"pascal",
461+
"objectpascal",
462+
"ada",
463+
"nim",
464+
"arm",
465+
"asm",
466+
"vala",
467+
"crystal",
468+
"kotlin",
469+
"zig"
470+
]
471+
},
472+
"variables": {
473+
"FileBasenameNoExt": "code-debug.getFileBasenameNoExt",
474+
"FileNameNoExt": "code-debug.getFileNameNoExt"
475+
},
476+
"configurationAttributes": {
477+
"attach": {
478+
"required": [
479+
"src_dir",
480+
"cros_sdk_path",
481+
"gdbpath",
482+
"executable",
483+
"cwd",
484+
"target"
485+
],
486+
"properties": {
487+
"src_dir": {
488+
"type": "string",
489+
"description": "Directory of CrOS source code (outside chroot)"
490+
},
491+
"cros_sdk_path": {
492+
"type": "string",
493+
"description": "Path to cros_sdk executable (outside chroot)"
494+
},
495+
"gdbpath": {
496+
"type": "string",
497+
"description": "Path to gdb executable (inside chroot)"
498+
},
499+
"debugger_args": {
500+
"type": "string",
501+
"description": "Arguments to pass to gdb"
502+
},
503+
"executable": {
504+
"type": "string",
505+
"description": "Path to the target debug executable (inside chroot)"
506+
},
507+
"target": {
508+
"type": "string",
509+
"description": "Target to attach to (inside chroot)"
510+
},
511+
"cacheThreads": {
512+
"type": "boolean",
513+
"description": "Set to true to cache the threads list on attach. This will save time for targets with a reasonably stable lot of threads",
514+
"default": false
515+
},
516+
"valuesFormatting": {
517+
"type": "string",
518+
"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",
519+
"default": "parseText",
520+
"enum": [
521+
"disabled",
522+
"parseText",
523+
"prettyPrinters"
524+
]
525+
},
526+
"printCalls": {
527+
"type": "boolean",
528+
"description": "Prints all GDB calls to the console",
529+
"default": false
530+
},
531+
"showDevDebugOutput": {
532+
"type": "boolean",
533+
"description": "Prints all GDB responses to the console",
534+
"default": false
535+
},
536+
"autorun": {
537+
"type": "array",
538+
"description": "GDB commands to run when starting to debug",
539+
"default": []
540+
}
541+
}
542+
}
543+
},
544+
"initialConfigurations": [
545+
{
546+
"name": "Debug",
547+
"type": "crosgdb",
548+
"request": "attach",
549+
"target": "./bin/executable",
550+
"cwd": "${workspaceRoot}",
551+
"valuesFormatting": "parseText"
552+
}
553+
],
554+
"configurationSnippets": [
555+
{
556+
"label": "GDB: Launch Program",
557+
"description": "Starts the program using gdb",
558+
"body": {
559+
"type": "crosgdb",
560+
"request": "attach",
561+
"src_dir": "/home/user/s/cros/src",
562+
"cros_sdk_path": "/home/user/bin/depot_tools/cros_sdk",
563+
"gdbpath": "/usr/bin/x86_64-cros-linux-gdb",
564+
"debugger_args": "",
565+
"executable": "/build/atlas/usr/lib/debug/boot/vmlinux"
566+
}
567+
}
568+
]
569+
},
442570
{
443571
"type": "lldb-mi",
444572
"extensions": [],

src/backend/mi2/mi2.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,23 @@ export class MI2 extends EventEmitter implements IBackend {
260260
});
261261
}
262262

263+
chroot_connect(cwd: string, sdk: string, gdb: string, executable: string, target: string): Thenable<any> {
264+
return new Promise((resolve, reject) => {
265+
let args = [gdb, '--interpreter=mi2', executable];
266+
this.process = ChildProcess.spawn(sdk, args, { cwd: cwd, env: this.procEnv });
267+
this.process.stdout.on("data", this.stdout.bind(this));
268+
this.process.stderr.on("data", this.stderr.bind(this));
269+
this.process.on("exit", (() => { this.emit("quit"); }).bind(this));
270+
this.process.on("error", ((err) => { this.emit("launcherror", err); }).bind(this));
271+
Promise.all([
272+
this.sendCommand("target-select remote " + target)
273+
]).then(() => {
274+
this.emit("debug-ready");
275+
resolve();
276+
}, reject);
277+
});
278+
}
279+
263280
stdout(data) {
264281
if (trace)
265282
this.log("stderr", "stdout: " + data);
@@ -346,6 +363,8 @@ export class MI2 extends EventEmitter implements IBackend {
346363
this.log("stderr", "stop: " + reason);
347364
if (reason == "breakpoint-hit")
348365
this.emit("breakpoint", parsed);
366+
else if (reason == "kgdb_breakpoint")
367+
this.emit("breakpoint", parsed);
349368
else if (reason == "end-stepping-range")
350369
this.emit("step-end", parsed);
351370
else if (reason == "function-finished")

src/crosgdb.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { MI2DebugSession } from './mibase';
2+
import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from 'vscode-debugadapter';
3+
import { DebugProtocol } from 'vscode-debugprotocol';
4+
import { MI2 } from "./backend/mi2/mi2";
5+
import { SSHArguments, ValuesFormattingMode } from './backend/backend';
6+
7+
8+
export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
9+
none: string;
10+
}
11+
12+
export interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
13+
src_dir: string;
14+
cros_sdk_path: string;
15+
gdbpath: string;
16+
debugger_args: string[];
17+
cache_threads: boolean;
18+
executable: string;
19+
target: string;
20+
valuesFormatting: ValuesFormattingMode;
21+
printCalls: boolean;
22+
showDevDebugOutput: boolean;
23+
autorun: string[];
24+
}
25+
26+
class CrosGDBDebugSession extends MI2DebugSession {
27+
protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
28+
response.body.supportsGotoTargetsRequest = true;
29+
response.body.supportsHitConditionalBreakpoints = true;
30+
response.body.supportsConfigurationDoneRequest = true;
31+
response.body.supportsConditionalBreakpoints = true;
32+
response.body.supportsFunctionBreakpoints = true;
33+
response.body.supportsEvaluateForHovers = true;
34+
response.body.supportsSetVariable = true;
35+
response.body.supportsStepBack = true;
36+
this.sendResponse(response);
37+
}
38+
39+
protected launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void {
40+
}
41+
42+
protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments): void {
43+
this.miDebugger = new MI2(args.cros_sdk_path, [], [], null);
44+
this.initDebugger();
45+
this.quit = false;
46+
this.attached = true;
47+
this.needContinue = true;
48+
this.translatePaths = true;
49+
this.debugReady = false;
50+
51+
this.switchCWD = "/mnt/host/source/src";
52+
this.trimCWD = args.src_dir;
53+
54+
this.setValuesFormattingMode(args.valuesFormatting);
55+
56+
this.miDebugger.cacheThreads = args.cache_threads;
57+
this.miDebugger.printCalls = !!args.printCalls;
58+
this.miDebugger.debugOutput = !!args.showDevDebugOutput;
59+
60+
this.miDebugger.chroot_connect(args.src_dir, args.cros_sdk_path, args.gdbpath, args.executable, args.target).then(() => {
61+
if (args.autorun)
62+
args.autorun.forEach(command => {
63+
this.miDebugger.sendUserInput(command);
64+
});
65+
this.sendResponse(response);
66+
}, err => {
67+
this.sendErrorResponse(response, 102, `Failed to attach: ${err.toString()}`);
68+
});
69+
}
70+
}
71+
72+
DebugSession.run(CrosGDBDebugSession);

0 commit comments

Comments
 (0)