Commit 31850be1 authored by Simon Zünd's avatar Simon Zünd Committed by V8 LUCI CQ

[inspector] Introduce status result for Debugger.setScriptSource

This CL introduces a new `status` enum returned by setScriptSource.
We'll use the information in the DevTools frontend to show more
meaningful error messages as well as disambiguate compilation errors
from failed live edits.

Drive-by: Deprecate the sync and async stack traces in the result.
Currently `setScriptSource` is guaranteed to stay paused so there
is no need to send along the same information from the
preceeding `Debugger.paused` event.
In the future we will restart the top-most frame once we allow
the top-most frame to be edited. In that case the inspector
fires Debugger.resumed + Debugger.paused events following the
live edit also making the info returned here superfluous.

R=jarin@chromium.org

Bug: chromium:1334484
Change-Id: I4226491caed72013a00927273c523213d797a766
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3691850
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81031}
parent 50c4365b
...@@ -452,14 +452,22 @@ domain Debugger ...@@ -452,14 +452,22 @@ domain Debugger
optional boolean dryRun optional boolean dryRun
returns returns
# New stack trace in case editing has happened while VM was stopped. # New stack trace in case editing has happened while VM was stopped.
optional array of CallFrame callFrames deprecated optional array of CallFrame callFrames
# Whether current call stack was modified after applying the changes. # Whether current call stack was modified after applying the changes.
optional boolean stackChanged deprecated optional boolean stackChanged
# Async stack trace, if any. # Async stack trace, if any.
optional Runtime.StackTrace asyncStackTrace deprecated optional Runtime.StackTrace asyncStackTrace
# Async stack trace, if any. # Async stack trace, if any.
experimental optional Runtime.StackTraceId asyncStackTraceId deprecated optional Runtime.StackTraceId asyncStackTraceId
# Exception details if any. # Whether the operation was successful or not. Only `Ok` denotes a
# successful live edit while the other enum variants denote why
# the live edit failed.
experimental enum status
Ok
CompileError
BlockedByActiveGenerator
BlockedByActiveFunction
# Exception details if any. Only present when `status` is `CompileError`.
optional Runtime.ExceptionDetails exceptionDetails optional Runtime.ExceptionDetails exceptionDetails
# Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc). # Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc).
......
...@@ -1002,12 +1002,29 @@ Response V8DebuggerAgentImpl::searchInContent( ...@@ -1002,12 +1002,29 @@ Response V8DebuggerAgentImpl::searchInContent(
return Response::Success(); return Response::Success();
} }
namespace {
const char* buildStatus(v8::debug::LiveEditResult::Status status) {
switch (status) {
case v8::debug::LiveEditResult::OK:
return protocol::Debugger::SetScriptSource::StatusEnum::Ok;
case v8::debug::LiveEditResult::COMPILE_ERROR:
return protocol::Debugger::SetScriptSource::StatusEnum::CompileError;
case v8::debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION:
return protocol::Debugger::SetScriptSource::StatusEnum::
BlockedByActiveFunction;
case v8::debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR:
return protocol::Debugger::SetScriptSource::StatusEnum::
BlockedByActiveGenerator;
}
}
} // namespace
Response V8DebuggerAgentImpl::setScriptSource( Response V8DebuggerAgentImpl::setScriptSource(
const String16& scriptId, const String16& newContent, Maybe<bool> dryRun, const String16& scriptId, const String16& newContent, Maybe<bool> dryRun,
Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames, Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames,
Maybe<bool>* stackChanged, Maybe<bool>* stackChanged,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace, Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId, Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId, String16* status,
Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) { Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) {
if (!enabled()) return Response::ServerError(kDebuggerNotEnabled); if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
...@@ -1026,7 +1043,8 @@ Response V8DebuggerAgentImpl::setScriptSource( ...@@ -1026,7 +1043,8 @@ Response V8DebuggerAgentImpl::setScriptSource(
v8::debug::LiveEditResult result; v8::debug::LiveEditResult result;
it->second->setSource(newContent, dryRun.fromMaybe(false), &result); it->second->setSource(newContent, dryRun.fromMaybe(false), &result);
if (result.status != v8::debug::LiveEditResult::OK) { *status = buildStatus(result.status);
if (result.status == v8::debug::LiveEditResult::COMPILE_ERROR) {
*optOutCompileError = *optOutCompileError =
protocol::Runtime::ExceptionDetails::create() protocol::Runtime::ExceptionDetails::create()
.setExceptionId(m_inspector->nextExceptionId()) .setExceptionId(m_inspector->nextExceptionId())
...@@ -1037,15 +1055,7 @@ Response V8DebuggerAgentImpl::setScriptSource( ...@@ -1037,15 +1055,7 @@ Response V8DebuggerAgentImpl::setScriptSource(
: 0) : 0)
.build(); .build();
return Response::Success(); return Response::Success();
} else {
*stackChanged = result.stack_changed;
} }
std::unique_ptr<Array<CallFrame>> callFrames;
Response response = currentCallFrames(&callFrames);
if (!response.IsSuccess()) return response;
*newCallFrames = std::move(callFrames);
*asyncStackTrace = currentAsyncStackTrace();
*asyncStackTraceId = currentExternalStackTrace();
return Response::Success(); return Response::Success();
} }
......
...@@ -88,6 +88,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { ...@@ -88,6 +88,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
Maybe<bool>* optOutStackChanged, Maybe<bool>* optOutStackChanged,
Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace, Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace,
Maybe<protocol::Runtime::StackTraceId>* optOutAsyncStackTraceId, Maybe<protocol::Runtime::StackTraceId>* optOutAsyncStackTraceId,
String16* outStatus,
Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override; Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override;
Response restartFrame( Response restartFrame(
const String16& callFrameId, Maybe<String16> mode, const String16& callFrameId, Maybe<String16> mode,
......
...@@ -6,9 +6,7 @@ console.log message from function before patching: ...@@ -6,9 +6,7 @@ console.log message from function before patching:
} }
Debugger.setScriptSource result: Debugger.setScriptSource result:
{ {
callFrames : [ status : Ok
]
stackChanged : false
} }
console.log message from function after patching: console.log message from function after patching:
{ {
......
Breakpoint in liveedited script Breakpoint in liveedited script
Update script source Update script source
{ {
callFrames : [ status : Ok
]
stackChanged : false
} }
Set breakpoint Set breakpoint
{ {
......
...@@ -19,5 +19,6 @@ Running test: testSourceWithSyntaxError ...@@ -19,5 +19,6 @@ Running test: testSourceWithSyntaxError
lineNumber : 1 lineNumber : 1
text : Uncaught SyntaxError: Invalid or unexpected token text : Uncaught SyntaxError: Invalid or unexpected token
} }
status : CompileError
} }
} }
...@@ -2,9 +2,7 @@ Tests Debugger.setScriptSource ...@@ -2,9 +2,7 @@ Tests Debugger.setScriptSource
TestExpression(2,4) === 6 TestExpression(2,4) === 6
Update current script source 'a + b' -> 'a * b'.. Update current script source 'a + b' -> 'a * b'..
{ {
callFrames : [ status : Ok
]
stackChanged : false
} }
TestExpression(2,4) === 8 TestExpression(2,4) === 8
Update current script source 'a * b' -> 'a # b'.. Update current script source 'a * b' -> 'a # b'..
...@@ -15,5 +13,6 @@ Update current script source 'a * b' -> 'a # b'.. ...@@ -15,5 +13,6 @@ Update current script source 'a * b' -> 'a # b'..
lineNumber : 1 lineNumber : 1
text : Uncaught SyntaxError: Invalid or unexpected token text : Uncaught SyntaxError: Invalid or unexpected token
} }
status : CompileError
} }
TestExpression(2,4) === 8 TestExpression(2,4) === 8
...@@ -15,12 +15,7 @@ foo (foo.js:2:2) ...@@ -15,12 +15,7 @@ foo (foo.js:2:2)
(anonymous) (:0:0) (anonymous) (:0:0)
Debugger.setScriptSource result: Debugger.setScriptSource result:
{ {
exceptionDetails : { status : BlockedByActiveFunction
columnNumber : 0
exceptionId : <exceptionId>
lineNumber : 0
text :
}
} }
foo(42) result: foo(42) result:
{ {
......
...@@ -2,8 +2,6 @@ Don't crash when live editing an unused inner function [crbug.com/1328453] ...@@ -2,8 +2,6 @@ Don't crash when live editing an unused inner function [crbug.com/1328453]
{ {
id : <messageId> id : <messageId>
result : { result : {
callFrames : [ status : Ok
]
stackChanged : false
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment