[inspector] Fix positions for inline scripts with #sourceURL.

For inline scripts that have a `// #sourceURL=foo.js` annotation, the
V8 inspector (and by extension `Error.stack`) currently operates in
terms of the `foo.js`, i.e. doesn't give any hint about the actual
source, except for the line/column offsets reported upon scriptParsed.
However in case of stack frames (i.e. as part of `Error.stack` or as
part of the call frames reported via CDP), the line/column offsets are
relative to the actual source instead of relative to the `foo.js` part,
which - besides other things - makes post-processing of recorded stack
traces tricky (sometimes impossible).

This change adjusts the source positions reported for (inline) scripts
with sourceURL annotations to be relative to the (inline) script instead
of the surrounding document.

Bug: chromium:1183990
Fixed: chromium:578269
Change-Id: I74f2b93c22ec43ca796b6b51faa9df5b99cf03f9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3069289
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76097}
This commit is contained in:
Benedikt Meurer 2021-08-04 13:16:18 +02:00 committed by V8 LUCI CQ
parent 1b1b45726d
commit c2f30c2b3f
11 changed files with 104 additions and 87 deletions

View File

@ -175,6 +175,10 @@ bool Script::HasValidSource() {
return true;
}
bool Script::HasSourceURLComment() const {
return source_url().IsString() && String::cast(source_url()).length() != 0;
}
} // namespace internal
} // namespace v8

View File

@ -142,6 +142,9 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
// resource is accessible. Otherwise, always return true.
inline bool HasValidSource();
// If the script has a non-empty sourceURL comment.
inline bool HasSourceURLComment() const;
Object GetNameOrSourceURL();
// Retrieve source position from where eval was called.

View File

@ -68,7 +68,11 @@ int StackFrameInfo::GetLineNumber(Handle<StackFrameInfo> info) {
Handle<Script> script;
if (GetScript(isolate, info).ToHandle(&script)) {
int position = GetSourcePosition(info);
return Script::GetLineNumber(script, position) + 1;
int line_number = Script::GetLineNumber(script, position) + 1;
if (script->HasSourceURLComment()) {
line_number -= script->line_offset();
}
return line_number;
}
return Message::kNoLineNumberInfo;
}
@ -84,7 +88,13 @@ int StackFrameInfo::GetColumnNumber(Handle<StackFrameInfo> info) {
#endif // V8_ENABLE_WEBASSEMBLY
Handle<Script> script;
if (GetScript(isolate, info).ToHandle(&script)) {
return Script::GetColumnNumber(script, position) + 1;
int column_number = Script::GetColumnNumber(script, position) + 1;
if (script->HasSourceURLComment()) {
if (Script::GetLineNumber(script, position) == script->line_offset()) {
column_number -= script->column_offset();
}
}
return column_number;
}
return Message::kNoColumnInfo;
}

View File

@ -9,12 +9,12 @@ test (test.js:21:2)
foo (test.js:10:2)
-- Promise.then --
test (test.js:19:14)
test (test.js:12:14)
(anonymous) (expr1.js:0:0)
foo (test.js:12:2)
-- Promise.then --
test (test.js:19:14)
test (test.js:12:14)
(anonymous) (expr1.js:0:0)

View File

@ -1,16 +1,16 @@
Checks async stack for late .then handlers with gc
foo1 (test.js:11:2)
-- Promise.then --
test (test.js:18:14)
test (test.js:10:14)
(anonymous) (expr.js:0:0)
foo1 (test.js:11:2)
-- Promise.then --
test (test.js:22:14)
test (test.js:14:14)
(anonymous) (expr.js:0:0)
foo1 (test.js:11:2)
-- Promise.then --
test (test.js:24:14)
test (test.js:16:14)
(anonymous) (expr.js:0:0)

View File

@ -2,10 +2,10 @@ Checks that async stack contains setTimeout
inner1 (test.js:11:4)
foo1 (test.js:14:2)
-- setTimeout --
inner2 (test.js:18:4)
foo2 (test.js:20:2)
inner2 (test.js:11:4)
foo2 (test.js:13:2)
-- setTimeout --
inner3 (test.js:25:4)
foo3 (test.js:27:2)
inner3 (test.js:18:4)
foo3 (test.js:20:2)
(anonymous) (expr.js:0:0)

View File

@ -3,78 +3,78 @@ Checks created frame for async call chain
Running test: testPromise
foo1 (test.js:10:2)
-- Promise.then --
promise (test.js:20:14)
promise (test.js:12:14)
(anonymous) (expr.js:0:0)
Running test: testPromiseThen
foo1 (test.js:10:2)
-- Promise.then --
promiseThen (test.js:28:14)
promiseThen (test.js:20:14)
(anonymous) (expr.js:0:0)
foo2 (test.js:14:2)
-- Promise.then --
promiseThen (test.js:29:14)
promiseThen (test.js:21:14)
(anonymous) (expr.js:0:0)
Running test: testPromiseThenThen
foo1 (test.js:10:2)
-- Promise.then --
promiseThenThen (test.js:37:14)
promiseThenThen (test.js:29:14)
(anonymous) (expr.js:0:0)
foo1 (test.js:10:2)
-- Promise.then --
promiseThenThen (test.js:38:14)
promiseThenThen (test.js:30:14)
(anonymous) (expr.js:0:0)
foo2 (test.js:14:2)
-- Promise.then --
promiseThenThen (test.js:37:25)
promiseThenThen (test.js:29:25)
(anonymous) (expr.js:0:0)
Running test: testPromiseResolve
foo1 (test.js:10:2)
-- Promise.then --
promiseResolve (test.js:44:27)
promiseResolve (test.js:36:27)
(anonymous) (expr.js:0:0)
Running test: testPromiseReject
foo1 (test.js:10:2)
-- Promise.catch --
promiseReject (test.js:48:31)
promiseReject (test.js:40:31)
(anonymous) (expr.js:0:0)
Running test: testPromiseAll
foo1 (test.js:10:2)
-- Promise.then --
promiseAll (test.js:52:44)
promiseAll (test.js:44:44)
(anonymous) (expr.js:0:0)
Running test: testPromiseRace
foo1 (test.js:10:2)
-- Promise.then --
promiseRace (test.js:56:45)
promiseRace (test.js:48:45)
(anonymous) (expr.js:0:0)
Running test: testThenableJob1
foo1 (test.js:10:2)
-- Promise.then --
thenableJob1 (test.js:60:72)
thenableJob1 (test.js:52:72)
(anonymous) (expr.js:0:0)
Running test: testThenableJob2
foo1 (test.js:10:2)
-- Promise.then --
thenableJob2 (test.js:64:57)
thenableJob2 (test.js:56:57)
(anonymous) (expr.js:0:0)
@ -82,10 +82,10 @@ Running test: testSetTimeouts
foo1 (test.js:10:2)
(anonymous) (test.js:72:25)
-- setTimeout --
(anonymous) (test.js:72:6)
(anonymous) (test.js:64:6)
-- setTimeout --
(anonymous) (test.js:71:4)
(anonymous) (test.js:63:4)
-- setTimeout --
setTimeouts (test.js:70:2)
setTimeouts (test.js:62:2)
(anonymous) (expr.js:0:0)

View File

@ -3,94 +3,94 @@ Checks that async chains for promises are correct.
Running test: testPromise
foo1 (test.js:9:2)
-- Promise.then --
promise (test.js:19:14)
promise (test.js:12:14)
(anonymous) (testPromise.js:0:0)
Running test: testPromiseResolvedBySetTimeout
foo1 (test.js:9:2)
-- Promise.then --
promiseResolvedBySetTimeout (test.js:27:14)
promiseResolvedBySetTimeout (test.js:20:14)
(anonymous) (testPromiseResolvedBySetTimeout.js:0:0)
Running test: testPromiseAll
foo1 (test.js:9:2)
-- Promise.then --
promiseAll (test.js:37:35)
promiseAll (test.js:30:35)
(anonymous) (testPromiseAll.js:0:0)
Running test: testPromiseAllReverseOrder
foo1 (test.js:9:2)
-- Promise.then --
promiseAllReverseOrder (test.js:48:35)
promiseAllReverseOrder (test.js:41:35)
(anonymous) (testPromiseAllReverseOrder.js:0:0)
Running test: testPromiseRace
foo1 (test.js:9:2)
-- Promise.then --
promiseRace (test.js:59:36)
promiseRace (test.js:52:36)
(anonymous) (testPromiseRace.js:0:0)
Running test: testTwoChainedCallbacks
foo1 (test.js:9:2)
-- Promise.then --
twoChainedCallbacks (test.js:68:14)
twoChainedCallbacks (test.js:61:14)
(anonymous) (testTwoChainedCallbacks.js:0:0)
foo2 (test.js:13:2)
-- Promise.then --
twoChainedCallbacks (test.js:68:25)
twoChainedCallbacks (test.js:61:25)
(anonymous) (testTwoChainedCallbacks.js:0:0)
Running test: testPromiseResolve
foo1 (test.js:9:2)
-- Promise.then --
promiseResolve (test.js:74:27)
promiseResolve (test.js:67:27)
(anonymous) (testPromiseResolve.js:0:0)
foo2 (test.js:13:2)
-- Promise.then --
promiseResolve (test.js:74:38)
promiseResolve (test.js:67:38)
(anonymous) (testPromiseResolve.js:0:0)
Running test: testThenableJobResolvedInSetTimeout
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedInSetTimeout (test.js:86:40)
thenableJobResolvedInSetTimeout (test.js:79:40)
(anonymous) (testThenableJobResolvedInSetTimeout.js:0:0)
Running test: testThenableJobResolvedInSetTimeoutWithStack
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedInSetTimeoutWithStack (test.js:104:40)
thenableJobResolvedInSetTimeoutWithStack (test.js:97:40)
(anonymous) (testThenableJobResolvedInSetTimeoutWithStack.js:0:0)
Running test: testThenableJobResolvedByPromise
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedByPromise (test.js:118:40)
thenableJobResolvedByPromise (test.js:111:40)
(anonymous) (testThenableJobResolvedByPromise.js:0:0)
Running test: testThenableJobResolvedByPromiseWithStack
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedByPromiseWithStack (test.js:136:40)
thenableJobResolvedByPromiseWithStack (test.js:129:40)
(anonymous) (testThenableJobResolvedByPromiseWithStack.js:0:0)
Running test: testLateThenCallback
foo1 (test.js:9:2)
-- Promise.then --
lateThenCallback (test.js:145:12)
lateThenCallback (test.js:138:12)
(anonymous) (testLateThenCallback.js:0:0)
@ -98,36 +98,36 @@ Running test: testComplex
inner1 (test.js:154:6)
foo1 (test.js:156:4)
-- Promise.then --
complex (test.js:202:5)
complex (test.js:195:5)
(anonymous) (testComplex.js:0:0)
(anonymous) (test.js:207:8)
-- Promise.then --
(anonymous) (test.js:206:8)
(anonymous) (test.js:199:8)
-- Promise.then --
(anonymous) (test.js:205:6)
(anonymous) (test.js:198:6)
-- setTimeout --
complex (test.js:204:2)
complex (test.js:197:2)
(anonymous) (testComplex.js:0:0)
Running test: testReject
foo1 (test.js:9:2)
-- Promise.catch --
reject (test.js:217:31)
reject (test.js:210:31)
(anonymous) (testReject.js:0:0)
Running test: testFinally1
foo1 (test.js:9:2)
-- Promise.finally --
finally1 (test.js:221:33)
finally1 (test.js:214:33)
(anonymous) (testFinally1.js:0:0)
Running test: testFinally2
foo1 (test.js:9:2)
-- Promise.finally --
finally2 (test.js:225:34)
finally2 (test.js:218:34)
(anonymous) (testFinally2.js:0:0)

View File

@ -8,10 +8,10 @@ asyncFact (test.js:9:2)
asyncFact (test.js:11:2)
-- async function --
asyncFact (test.js:10:20)
asyncFact (test.js:10:20)
asyncFact (test.js:10:20)
asyncFact (test.js:10:20)
asyncFact (test.js:3:20)
asyncFact (test.js:3:20)
asyncFact (test.js:3:20)
asyncFact (test.js:3:20)
(anonymous) (expr.js:0:0)
@ -23,7 +23,7 @@ asyncFact (test.js:9:2)
asyncFact (test.js:11:2)
-- async function --
asyncFact (test.js:10:20)
asyncFact (test.js:3:20)
(anonymous) (expr.js:0:0)

View File

@ -164,7 +164,7 @@ Runtime.evaluate compiled script with stack trace
[0] : {
columnNumber : 2
functionName : fooTop
lineNumber : 10
lineNumber : 2
scriptId : <scriptId>
url : top-frame.js
}
@ -247,7 +247,7 @@ Runtime.evaluate compile script error with stack trace
[0] : {
columnNumber : 2
functionName : fooTopFail
lineNumber : 20
lineNumber : 2
scriptId : <scriptId>
url : top-frame-fail.js
}

View File

@ -14,7 +14,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 9
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
@ -46,7 +46,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 10
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
@ -78,7 +78,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 11
lineNumber : 4
scriptId : <scriptId>
url : test.js
}
@ -110,7 +110,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 12
lineNumber : 5
scriptId : <scriptId>
url : test.js
}
@ -142,7 +142,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 13
lineNumber : 6
scriptId : <scriptId>
url : test.js
}
@ -174,7 +174,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 14
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
@ -206,7 +206,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 15
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
@ -297,7 +297,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 16
lineNumber : 9
scriptId : <scriptId>
url : test.js
}
@ -378,7 +378,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 17
lineNumber : 10
scriptId : <scriptId>
url : test.js
}
@ -410,7 +410,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 18
lineNumber : 11
scriptId : <scriptId>
url : test.js
}
@ -442,7 +442,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 19
lineNumber : 12
scriptId : <scriptId>
url : test.js
}
@ -474,7 +474,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 20
lineNumber : 13
scriptId : <scriptId>
url : test.js
}
@ -506,7 +506,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 21
lineNumber : 14
scriptId : <scriptId>
url : test.js
}
@ -538,7 +538,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 22
lineNumber : 15
scriptId : <scriptId>
url : test.js
}
@ -570,7 +570,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 23
lineNumber : 16
scriptId : <scriptId>
url : test.js
}
@ -602,7 +602,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 24
lineNumber : 17
scriptId : <scriptId>
url : test.js
}
@ -634,7 +634,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 25
lineNumber : 18
scriptId : <scriptId>
url : test.js
}
@ -666,14 +666,14 @@ Checks console methods
[0] : {
columnNumber : 12
functionName : foo
lineNumber : 27
lineNumber : 20
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 2
functionName : testFunction
lineNumber : 29
lineNumber : 22
scriptId : <scriptId>
url : test.js
}
@ -705,14 +705,14 @@ Checks console methods
[0] : {
columnNumber : 12
functionName : foo
lineNumber : 27
lineNumber : 20
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 2
functionName : testFunction
lineNumber : 30
lineNumber : 23
scriptId : <scriptId>
url : test.js
}
@ -744,7 +744,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 31
lineNumber : 24
scriptId : <scriptId>
url : test.js
}
@ -776,7 +776,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 32
lineNumber : 25
scriptId : <scriptId>
url : test.js
}
@ -808,7 +808,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 33
lineNumber : 26
scriptId : <scriptId>
url : test.js
}
@ -840,7 +840,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 35
lineNumber : 28
scriptId : <scriptId>
url : test.js
}
@ -872,7 +872,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 37
lineNumber : 30
scriptId : <scriptId>
url : test.js
}
@ -904,7 +904,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 39
lineNumber : 32
scriptId : <scriptId>
url : test.js
}
@ -936,7 +936,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 40
lineNumber : 33
scriptId : <scriptId>
url : test.js
}
@ -968,7 +968,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 41
lineNumber : 34
scriptId : <scriptId>
url : test.js
}
@ -1001,7 +1001,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 42
lineNumber : 35
scriptId : <scriptId>
url : test.js
}
@ -1034,7 +1034,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 43
lineNumber : 36
scriptId : <scriptId>
url : test.js
}
@ -1067,7 +1067,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 44
lineNumber : 37
scriptId : <scriptId>
url : test.js
}
@ -1099,7 +1099,7 @@ Checks console methods
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 45
lineNumber : 38
scriptId : <scriptId>
url : test.js
}