Skip to content

Commit 0c1e3ae

Browse files
committed
src: make source list -l flag optional
`v8 source list` was expecting an undocumented flag -l, which is the first line the command will output from source code. This commit makes that flag optional, documents the flag, improves the help message for this command and adds tests for it. Fixes: #138 PR-URL: #259 Reviewed-By: Joyee Cheung <[email protected]>
1 parent a295239 commit 0c1e3ae

File tree

4 files changed

+91
-31
lines changed

4 files changed

+91
-31
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,11 @@ The following subcommands are supported:
262262
print -- Print short description of the JavaScript value.
263263
264264
Syntax: v8 print expr
265-
source -- Source code information
265+
source list -- Print source lines around the currently selected
266+
JavaScript frame.
267+
Syntax: v8 source list [flags]
268+
Flags:
269+
* -l <line> - Print source code below line <line>.
266270
267271
For more help on any particular subcommand, type 'help <command> <subcommand>'.
268272
```

src/llnode.cc

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,6 @@ bool PrintCmd::DoExecute(SBDebugger d, char** cmd,
194194

195195
bool ListCmd::DoExecute(SBDebugger d, char** cmd,
196196
SBCommandReturnObject& result) {
197-
if (cmd == nullptr || *cmd == nullptr) {
198-
result.SetError("USAGE: v8 source list\n");
199-
return false;
200-
}
201-
202197
static SBFrame last_frame;
203198
static uint64_t last_line = 0;
204199
SBTarget target = d.GetSelectedTarget();
@@ -212,22 +207,24 @@ bool ListCmd::DoExecute(SBDebugger d, char** cmd,
212207
bool grab_line = false;
213208
bool line_switch = false;
214209
int line_from_switch = 0;
215-
for (char** start = cmd; *start != nullptr; start++) {
216-
if (grab_line) {
217-
grab_line = false;
218-
line_switch = true;
219-
errno = 0;
220-
line_from_switch = strtol(*start, nullptr, 10);
221-
if (errno) {
222-
result.SetError("Invalid line number");
223-
return false;
210+
if (cmd != nullptr) {
211+
for (char** start = cmd; *start != nullptr; start++) {
212+
if (grab_line) {
213+
grab_line = false;
214+
line_switch = true;
215+
errno = 0;
216+
line_from_switch = strtol(*start, nullptr, 10);
217+
if (errno) {
218+
result.SetError("Invalid line number");
219+
return false;
220+
}
221+
line_from_switch--;
224222
}
225-
line_from_switch--;
226-
}
227-
if (strcmp(*start, "-l") == 0) {
228-
grab_line = true;
223+
if (strcmp(*start, "-l") == 0) {
224+
grab_line = true;
225+
}
226+
full_cmd += *start;
229227
}
230-
full_cmd += *start;
231228
}
232229
if (grab_line || (line_switch && line_from_switch < 0)) {
233230
result.SetError("Expected line number after -l");
@@ -434,8 +431,12 @@ bool PluginInitialize(SBDebugger d) {
434431
SBCommand source =
435432
v8.AddMultiwordCommand("source", "Source code information");
436433
source.AddCommand("list", new llnode::ListCmd(&llv8),
437-
"Print source lines around a selected JavaScript frame.\n\n"
438-
"Syntax: v8 source list\n");
434+
"Print source lines around the currently selected "
435+
"JavaScript frame.\n\n"
436+
"Syntax: v8 source list [flags]\n\n"
437+
"Flags:\n"
438+
" * -l <line> - Print source code below line <line>.\n"
439+
);
439440
interpreter.AddCommand("jssource", new llnode::ListCmd(&llv8),
440441
"Alias for `v8 source list`");
441442

test/plugin/frame-test.js

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,62 @@ const tape = require('tape');
44

55
const common = require('../common');
66

7+
const sourceCode = [
8+
"10 function eyecatcher() {",
9+
"11 crasher(); // # args < # formal parameters inserts an adaptor frame.",
10+
"12 return this; // Force definition of |this|.",
11+
"13 }",
12+
];
13+
const lastLine = new RegExp(sourceCode[sourceCode.length - 1]);
14+
15+
function fatalError(t, sess, err) {
16+
t.error(err);
17+
sess.quit();
18+
return t.end();
19+
}
20+
21+
function testFrameList(t, sess, frameNumber) {
22+
sess.send(`frame select ${frameNumber}`);
23+
sess.linesUntil(/frame/, (err, lines) => {
24+
if (err) {
25+
return fatalError(t, sess, err);
26+
}
27+
sess.send('v8 source list');
28+
29+
sess.linesUntil(/v8 source list/, (err, lines) => {
30+
sess.linesUntil(lastLine, (err, lines) => {
31+
if (err) {
32+
return fatalError(t, sess, err);
33+
}
34+
t.equal(lines.length, sourceCode.length,
35+
`v8 source list correct size`);
36+
for (let i = 0; i < lines.length; i++) {
37+
t.equal(lines[i].trim(), sourceCode[i], `v8 source list #${i}`);
38+
}
39+
40+
sess.send('v8 source list -l 2');
41+
42+
sess.linesUntil(/v8 source list/, (err, lines) => {
43+
sess.linesUntil(lastLine, (err, lines) => {
44+
if (err) {
45+
return fatalError(t, sess, err);
46+
}
47+
t.equal(lines.length, sourceCode.length - 1,
48+
`v8 source list -l 2 correct size`);
49+
for (let i = 0; i < lines.length; i++) {
50+
t.equal(lines[i].trim(), sourceCode[i + 1],
51+
`v8 source list -l 2 #${i}`);
52+
}
53+
54+
sess.quit();
55+
t.end();
56+
});
57+
});
58+
});
59+
});
60+
});
61+
}
62+
763
tape('v8 stack', (t) => {
864
t.timeoutAfter(15000);
965

@@ -43,7 +99,13 @@ tape('v8 stack', (t) => {
4399
// The test adds unreachable `return this` statements as a workaround.
44100
t.ok(/this=(0x[0-9a-f]+):<Global proxy>/.test(eyecatcher), 'global this');
45101
t.ok(/this=(0x[0-9a-f]+):<undefined>/.test(crasher), 'undefined this');
46-
sess.quit();
47-
t.end();
102+
103+
const eyecatcherFrame = eyecatcher.match(/frame #([0-9]+)/)[1];
104+
if (!eyecatcherFrame) {
105+
fatalError(t, sess, "Couldn't determine eyecather's frame number");
106+
}
107+
108+
testFrameList(t, sess, eyecatcherFrame);
109+
48110
});
49111
});

test/plugin/usage-test.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,6 @@ tape('usage messages', (t) => {
2020
t.error(err);
2121
const re = /^error: USAGE: v8 print expr$/;
2222
t.ok(containsLine(lines, re), 'print usage message');
23-
sess.send('v8 source list');
24-
});
25-
26-
sess.stderr.linesUntil(/USAGE/, (err, lines) => {
27-
t.error(err);
28-
const re = /^error: USAGE: v8 source list$/;
29-
t.ok(containsLine(lines, re), 'list usage message');
3023
sess.send('v8 findjsinstances');
3124
});
3225

0 commit comments

Comments
 (0)