Commit b9015910 authored by Aleksei Koziatinskii's avatar Aleksei Koziatinskii Committed by Commit Bot

inspector: added Debugger.setInstrumentationBreakpoint method

There are two possible type:
- scriptParsed - breakpoint for any script,
- scriptWithSourceMapParsed - breakpoint for script with
  sourceMappingURL.

When one of the breakpoints is set then for each matched script
we add breakpoint on call to top level function of that script.

Node: https://github.com/nodejs/node/issues/24687

R=dgozman@chromium.org

Bug: chromium:887384,chromium:724793,chromium:882909
Change-Id: I9c08b2a2a5ba7006adfedd85fc92ae191517af00
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1354245Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: 's avatarAlexei Filippov <alph@chromium.org>
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61353}
parent 89ed6b76
...@@ -9388,6 +9388,19 @@ bool debug::Script::SetBreakpoint(v8::Local<v8::String> condition, ...@@ -9388,6 +9388,19 @@ bool debug::Script::SetBreakpoint(v8::Local<v8::String> condition,
return true; return true;
} }
bool debug::Script::SetBreakpointOnScriptEntry(BreakpointId* id) const {
i::Handle<i::Script> script = Utils::OpenHandle(this);
i::Isolate* isolate = script->GetIsolate();
i::SharedFunctionInfo::ScriptIterator it(isolate, *script);
for (i::SharedFunctionInfo sfi = it.Next(); !sfi.is_null(); sfi = it.Next()) {
if (sfi->is_toplevel()) {
return isolate->debug()->SetBreakpointForFunction(
handle(sfi, isolate), isolate->factory()->empty_string(), id);
}
}
return false;
}
void debug::RemoveBreakpoint(Isolate* v8_isolate, BreakpointId id) { void debug::RemoveBreakpoint(Isolate* v8_isolate, BreakpointId id) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
i::HandleScope handle_scope(isolate); i::HandleScope handle_scope(isolate);
...@@ -9781,8 +9794,8 @@ bool debug::SetFunctionBreakpoint(v8::Local<v8::Function> function, ...@@ -9781,8 +9794,8 @@ bool debug::SetFunctionBreakpoint(v8::Local<v8::Function> function,
i::Handle<i::String> condition_string = i::Handle<i::String> condition_string =
condition.IsEmpty() ? isolate->factory()->empty_string() condition.IsEmpty() ? isolate->factory()->empty_string()
: Utils::OpenHandle(*condition); : Utils::OpenHandle(*condition);
return isolate->debug()->SetBreakpointForFunction(jsfunction, return isolate->debug()->SetBreakpointForFunction(
condition_string, id); handle(jsfunction->shared(), isolate), condition_string, id);
} }
debug::PostponeInterruptsScope::PostponeInterruptsScope(v8::Isolate* isolate) debug::PostponeInterruptsScope::PostponeInterruptsScope(v8::Isolate* isolate)
......
...@@ -147,6 +147,7 @@ class V8_EXPORT_PRIVATE Script { ...@@ -147,6 +147,7 @@ class V8_EXPORT_PRIVATE Script {
LiveEditResult* result) const; LiveEditResult* result) const;
bool SetBreakpoint(v8::Local<v8::String> condition, debug::Location* location, bool SetBreakpoint(v8::Local<v8::String> condition, debug::Location* location,
BreakpointId* id) const; BreakpointId* id) const;
bool SetBreakpointOnScriptEntry(BreakpointId* id) const;
}; };
// Specialization for wasm Scripts. // Specialization for wasm Scripts.
......
...@@ -589,13 +589,12 @@ bool Debug::CheckBreakPoint(Handle<BreakPoint> break_point, ...@@ -589,13 +589,12 @@ bool Debug::CheckBreakPoint(Handle<BreakPoint> break_point,
return result->BooleanValue(isolate_); return result->BooleanValue(isolate_);
} }
bool Debug::SetBreakPoint(Handle<JSFunction> function, bool Debug::SetBreakpoint(Handle<SharedFunctionInfo> shared,
Handle<BreakPoint> break_point, Handle<BreakPoint> break_point,
int* source_position) { int* source_position) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
// Make sure the function is compiled and has set up the debug info. // Make sure the function is compiled and has set up the debug info.
Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
if (!EnsureBreakInfo(shared)) return false; if (!EnsureBreakInfo(shared)) return false;
PrepareFunctionForDebugExecution(shared); PrepareFunctionForDebugExecution(shared);
...@@ -750,13 +749,13 @@ int Debug::GetFunctionDebuggingId(Handle<JSFunction> function) { ...@@ -750,13 +749,13 @@ int Debug::GetFunctionDebuggingId(Handle<JSFunction> function) {
return id; return id;
} }
bool Debug::SetBreakpointForFunction(Handle<JSFunction> function, bool Debug::SetBreakpointForFunction(Handle<SharedFunctionInfo> shared,
Handle<String> condition, int* id) { Handle<String> condition, int* id) {
*id = ++thread_local_.last_breakpoint_id_; *id = ++thread_local_.last_breakpoint_id_;
Handle<BreakPoint> breakpoint = Handle<BreakPoint> breakpoint =
isolate_->factory()->NewBreakPoint(*id, condition); isolate_->factory()->NewBreakPoint(*id, condition);
int source_position = 0; int source_position = 0;
return SetBreakPoint(function, breakpoint, &source_position); return SetBreakpoint(shared, breakpoint, &source_position);
} }
void Debug::RemoveBreakpoint(int id) { void Debug::RemoveBreakpoint(int id) {
......
...@@ -227,7 +227,7 @@ class V8_EXPORT_PRIVATE Debug { ...@@ -227,7 +227,7 @@ class V8_EXPORT_PRIVATE Debug {
Handle<FixedArray> GetLoadedScripts(); Handle<FixedArray> GetLoadedScripts();
// Break point handling. // Break point handling.
bool SetBreakPoint(Handle<JSFunction> function, bool SetBreakpoint(Handle<SharedFunctionInfo> shared,
Handle<BreakPoint> break_point, int* source_position); Handle<BreakPoint> break_point, int* source_position);
void ClearBreakPoint(Handle<BreakPoint> break_point); void ClearBreakPoint(Handle<BreakPoint> break_point);
void ChangeBreakOnException(ExceptionBreakType type, bool enable); void ChangeBreakOnException(ExceptionBreakType type, bool enable);
...@@ -235,7 +235,7 @@ class V8_EXPORT_PRIVATE Debug { ...@@ -235,7 +235,7 @@ class V8_EXPORT_PRIVATE Debug {
bool SetBreakPointForScript(Handle<Script> script, Handle<String> condition, bool SetBreakPointForScript(Handle<Script> script, Handle<String> condition,
int* source_position, int* id); int* source_position, int* id);
bool SetBreakpointForFunction(Handle<JSFunction> function, bool SetBreakpointForFunction(Handle<SharedFunctionInfo> shared,
Handle<String> condition, int* id); Handle<String> condition, int* id);
void RemoveBreakpoint(int id); void RemoveBreakpoint(int id);
......
...@@ -317,6 +317,17 @@ domain Debugger ...@@ -317,6 +317,17 @@ domain Debugger
# Location this breakpoint resolved into. # Location this breakpoint resolved into.
Location actualLocation Location actualLocation
# Sets instrumentation breakpoint.
command setInstrumentationBreakpoint
parameters
# Instrumentation name.
enum instrumentation
beforeScriptExecution
beforeScriptWithSourceMapExecution
returns
# Id of the created breakpoint for further reference.
BreakpointId breakpointId
# Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this # Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this
# command is issued, all existing parsed scripts will have breakpoints resolved and returned in # command is issued, all existing parsed scripts will have breakpoints resolved and returned in
# `locations` property. Further matching script parsing will result in subsequent # `locations` property. Further matching script parsing will result in subsequent
...@@ -449,16 +460,17 @@ domain Debugger ...@@ -449,16 +460,17 @@ domain Debugger
array of CallFrame callFrames array of CallFrame callFrames
# Pause reason. # Pause reason.
enum reason enum reason
XHR ambiguous
assert
debugCommand
DOM DOM
EventListener EventListener
exception exception
assert instrumentation
debugCommand
promiseRejection
OOM OOM
other other
ambiguous promiseRejection
XHR
# Object containing break-specific auxiliary properties. # Object containing break-specific auxiliary properties.
optional object data optional object data
# Hit breakpoints IDs # Hit breakpoints IDs
......
...@@ -31,10 +31,13 @@ using protocol::Array; ...@@ -31,10 +31,13 @@ using protocol::Array;
using protocol::Maybe; using protocol::Maybe;
using protocol::Debugger::BreakpointId; using protocol::Debugger::BreakpointId;
using protocol::Debugger::CallFrame; using protocol::Debugger::CallFrame;
using protocol::Debugger::Scope;
using protocol::Runtime::ExceptionDetails; using protocol::Runtime::ExceptionDetails;
using protocol::Runtime::ScriptId;
using protocol::Runtime::RemoteObject; using protocol::Runtime::RemoteObject;
using protocol::Debugger::Scope; using protocol::Runtime::ScriptId;
namespace InstrumentationEnum =
protocol::Debugger::SetInstrumentationBreakpoint::InstrumentationEnum;
namespace DebuggerAgentState { namespace DebuggerAgentState {
static const char pauseOnExceptionsState[] = "pauseOnExceptionsState"; static const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
...@@ -47,6 +50,7 @@ static const char breakpointsByRegex[] = "breakpointsByRegex"; ...@@ -47,6 +50,7 @@ static const char breakpointsByRegex[] = "breakpointsByRegex";
static const char breakpointsByUrl[] = "breakpointsByUrl"; static const char breakpointsByUrl[] = "breakpointsByUrl";
static const char breakpointsByScriptHash[] = "breakpointsByScriptHash"; static const char breakpointsByScriptHash[] = "breakpointsByScriptHash";
static const char breakpointHints[] = "breakpointHints"; static const char breakpointHints[] = "breakpointHints";
static const char instrumentationBreakpoints[] = "instrumentationBreakpoints";
} // namespace DebuggerAgentState } // namespace DebuggerAgentState
...@@ -80,7 +84,8 @@ enum class BreakpointType { ...@@ -80,7 +84,8 @@ enum class BreakpointType {
kByScriptId, kByScriptId,
kDebugCommand, kDebugCommand,
kMonitorCommand, kMonitorCommand,
kBreakpointAtEntry kBreakpointAtEntry,
kInstrumentationBreakpoint
}; };
String16 generateBreakpointId(BreakpointType type, String16 generateBreakpointId(BreakpointType type,
...@@ -106,6 +111,15 @@ String16 generateBreakpointId(BreakpointType type, ...@@ -106,6 +111,15 @@ String16 generateBreakpointId(BreakpointType type,
return builder.toString(); return builder.toString();
} }
String16 generateInstrumentationBreakpointId(const String16& instrumentation) {
String16Builder builder;
builder.appendNumber(
static_cast<int>(BreakpointType::kInstrumentationBreakpoint));
builder.append(':');
builder.append(instrumentation);
return builder.toString();
}
bool parseBreakpointId(const String16& breakpointId, BreakpointType* type, bool parseBreakpointId(const String16& breakpointId, BreakpointType* type,
String16* scriptSelector = nullptr, String16* scriptSelector = nullptr,
int* lineNumber = nullptr, int* columnNumber = nullptr) { int* lineNumber = nullptr, int* columnNumber = nullptr) {
...@@ -114,14 +128,15 @@ bool parseBreakpointId(const String16& breakpointId, BreakpointType* type, ...@@ -114,14 +128,15 @@ bool parseBreakpointId(const String16& breakpointId, BreakpointType* type,
int rawType = breakpointId.substring(0, typeLineSeparator).toInteger(); int rawType = breakpointId.substring(0, typeLineSeparator).toInteger();
if (rawType < static_cast<int>(BreakpointType::kByUrl) || if (rawType < static_cast<int>(BreakpointType::kByUrl) ||
rawType > static_cast<int>(BreakpointType::kBreakpointAtEntry)) { rawType > static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
return false; return false;
} }
if (type) *type = static_cast<BreakpointType>(rawType); if (type) *type = static_cast<BreakpointType>(rawType);
if (rawType == static_cast<int>(BreakpointType::kDebugCommand) || if (rawType == static_cast<int>(BreakpointType::kDebugCommand) ||
rawType == static_cast<int>(BreakpointType::kMonitorCommand) || rawType == static_cast<int>(BreakpointType::kMonitorCommand) ||
rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry)) { rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry) ||
// The script and source position is not encoded in this case. rawType == static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
// The script and source position are not encoded in this case.
return true; return true;
} }
...@@ -356,6 +371,7 @@ Response V8DebuggerAgentImpl::disable() { ...@@ -356,6 +371,7 @@ Response V8DebuggerAgentImpl::disable() {
m_state->remove(DebuggerAgentState::breakpointsByUrl); m_state->remove(DebuggerAgentState::breakpointsByUrl);
m_state->remove(DebuggerAgentState::breakpointsByScriptHash); m_state->remove(DebuggerAgentState::breakpointsByScriptHash);
m_state->remove(DebuggerAgentState::breakpointHints); m_state->remove(DebuggerAgentState::breakpointHints);
m_state->remove(DebuggerAgentState::instrumentationBreakpoints);
m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
v8::debug::NoBreakOnException); v8::debug::NoBreakOnException);
...@@ -580,6 +596,20 @@ Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall( ...@@ -580,6 +596,20 @@ Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall(
return Response::OK(); return Response::OK();
} }
Response V8DebuggerAgentImpl::setInstrumentationBreakpoint(
const String16& instrumentation, String16* outBreakpointId) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled);
String16 breakpointId = generateInstrumentationBreakpointId(instrumentation);
protocol::DictionaryValue* breakpoints = getOrCreateObject(
m_state, DebuggerAgentState::instrumentationBreakpoints);
if (breakpoints->get(breakpointId)) {
return Response::Error("Instrumentation breakpoint is already enabled.");
}
breakpoints->setBoolean(breakpointId, true);
*outBreakpointId = breakpointId;
return Response::OK();
}
Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled); if (!enabled()) return Response::Error(kDebuggerNotEnabled);
BreakpointType type; BreakpointType type;
...@@ -606,6 +636,10 @@ Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { ...@@ -606,6 +636,10 @@ Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
case BreakpointType::kByUrlRegex: case BreakpointType::kByUrlRegex:
breakpoints = m_state->getObject(DebuggerAgentState::breakpointsByRegex); breakpoints = m_state->getObject(DebuggerAgentState::breakpointsByRegex);
break; break;
case BreakpointType::kInstrumentationBreakpoint:
breakpoints =
m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
break;
default: default:
break; break;
} }
...@@ -1496,6 +1530,40 @@ void V8DebuggerAgentImpl::didParseSource( ...@@ -1496,6 +1530,40 @@ void V8DebuggerAgentImpl::didParseSource(
m_frontend.breakpointResolved(breakpointId, std::move(location)); m_frontend.breakpointResolved(breakpointId, std::move(location));
} }
} }
setScriptInstrumentationBreakpointIfNeeded(scriptRef);
}
void V8DebuggerAgentImpl::setScriptInstrumentationBreakpointIfNeeded(
V8DebuggerScript* scriptRef) {
protocol::DictionaryValue* breakpoints =
m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
if (!breakpoints) return;
bool isBlackboxed = isFunctionBlackboxed(
scriptRef->scriptId(), v8::debug::Location(0, 0),
v8::debug::Location(scriptRef->endLine(), scriptRef->endColumn()));
if (isBlackboxed) return;
String16 sourceMapURL = scriptRef->sourceMappingURL();
String16 breakpointId = generateInstrumentationBreakpointId(
InstrumentationEnum::BeforeScriptExecution);
if (!breakpoints->get(breakpointId)) {
if (sourceMapURL.isEmpty()) return;
breakpointId = generateInstrumentationBreakpointId(
InstrumentationEnum::BeforeScriptWithSourceMapExecution);
if (!breakpoints->get(breakpointId)) return;
}
v8::debug::BreakpointId debuggerBreakpointId;
if (!scriptRef->setBreakpointOnRun(&debuggerBreakpointId)) return;
std::unique_ptr<protocol::DictionaryValue> data =
protocol::DictionaryValue::create();
data->setString("url", scriptRef->sourceURL());
data->setString("scriptId", scriptRef->scriptId());
if (!sourceMapURL.isEmpty()) data->setString("sourceMapURL", sourceMapURL);
m_breakpointsOnScriptRun[debuggerBreakpointId] = std::move(data);
m_debuggerBreakpointIdToBreakpointId[debuggerBreakpointId] = breakpointId;
m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
debuggerBreakpointId);
} }
void V8DebuggerAgentImpl::didPause( void V8DebuggerAgentImpl::didPause(
...@@ -1539,6 +1607,14 @@ void V8DebuggerAgentImpl::didPause( ...@@ -1539,6 +1607,14 @@ void V8DebuggerAgentImpl::didPause(
std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create(); std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create();
for (const auto& id : hitBreakpoints) { for (const auto& id : hitBreakpoints) {
auto it = m_breakpointsOnScriptRun.find(id);
if (it != m_breakpointsOnScriptRun.end()) {
hitReasons.push_back(std::make_pair(
protocol::Debugger::Paused::ReasonEnum::Instrumentation,
std::move(it->second)));
m_breakpointsOnScriptRun.erase(it);
continue;
}
auto breakpointIterator = m_debuggerBreakpointIdToBreakpointId.find(id); auto breakpointIterator = m_debuggerBreakpointIdToBreakpointId.find(id);
if (breakpointIterator == m_debuggerBreakpointIdToBreakpointId.end()) { if (breakpointIterator == m_debuggerBreakpointIdToBreakpointId.end()) {
continue; continue;
......
...@@ -60,6 +60,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { ...@@ -60,6 +60,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
Response setBreakpointOnFunctionCall(const String16& functionObjectId, Response setBreakpointOnFunctionCall(const String16& functionObjectId,
Maybe<String16> optionalCondition, Maybe<String16> optionalCondition,
String16* outBreakpointId) override; String16* outBreakpointId) override;
Response setInstrumentationBreakpoint(const String16& instrumentation,
String16* outBreakpointId) override;
Response removeBreakpoint(const String16& breakpointId) override; Response removeBreakpoint(const String16& breakpointId) override;
Response continueToLocation(std::unique_ptr<protocol::Debugger::Location>, Response continueToLocation(std::unique_ptr<protocol::Debugger::Location>,
Maybe<String16> targetCallFrames) override; Maybe<String16> targetCallFrames) override;
...@@ -184,6 +186,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { ...@@ -184,6 +186,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
bool isPaused() const; bool isPaused() const;
void setScriptInstrumentationBreakpointIfNeeded(V8DebuggerScript* script);
using ScriptsMap = using ScriptsMap =
std::unordered_map<String16, std::unique_ptr<V8DebuggerScript>>; std::unordered_map<String16, std::unique_ptr<V8DebuggerScript>>;
using BreakpointIdToDebuggerBreakpointIdsMap = using BreakpointIdToDebuggerBreakpointIdsMap =
...@@ -201,6 +205,9 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { ...@@ -201,6 +205,9 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
ScriptsMap m_scripts; ScriptsMap m_scripts;
BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds; BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds;
DebuggerBreakpointIdToBreakpointIdMap m_debuggerBreakpointIdToBreakpointId; DebuggerBreakpointIdToBreakpointIdMap m_debuggerBreakpointIdToBreakpointId;
std::unordered_map<v8::debug::BreakpointId,
std::unique_ptr<protocol::DictionaryValue>>
m_breakpointsOnScriptRun;
size_t m_maxScriptCacheSize = 0; size_t m_maxScriptCacheSize = 0;
size_t m_cachedScriptSize = 0; size_t m_cachedScriptSize = 0;
......
...@@ -235,6 +235,11 @@ class ActualScript : public V8DebuggerScript { ...@@ -235,6 +235,11 @@ class ActualScript : public V8DebuggerScript {
id); id);
} }
bool setBreakpointOnRun(int* id) const override {
v8::HandleScope scope(m_isolate);
return script()->SetBreakpointOnScriptEntry(id);
}
const String16& hash() const override { const String16& hash() const override {
if (!m_hash.isEmpty()) return m_hash; if (!m_hash.isEmpty()) return m_hash;
v8::HandleScope scope(m_isolate); v8::HandleScope scope(m_isolate);
...@@ -424,6 +429,8 @@ class WasmVirtualScript : public V8DebuggerScript { ...@@ -424,6 +429,8 @@ class WasmVirtualScript : public V8DebuggerScript {
return true; return true;
} }
bool setBreakpointOnRun(int*) const override { return false; }
const String16& hash() const override { const String16& hash() const override {
if (m_hash.isEmpty()) { if (m_hash.isEmpty()) {
m_hash = m_wasmTranslation->GetHash(m_id, m_functionIndex); m_hash = m_wasmTranslation->GetHash(m_id, m_functionIndex);
......
...@@ -90,6 +90,7 @@ class V8DebuggerScript { ...@@ -90,6 +90,7 @@ class V8DebuggerScript {
virtual bool setBreakpoint(const String16& condition, virtual bool setBreakpoint(const String16& condition,
v8::debug::Location* location, int* id) const = 0; v8::debug::Location* location, int* id) const = 0;
virtual void MakeWeak() = 0; virtual void MakeWeak() = 0;
virtual bool setBreakpointOnRun(int* id) const = 0;
protected: protected:
V8DebuggerScript(v8::Isolate*, String16 id, String16 url); V8DebuggerScript(v8::Isolate*, String16 id, String16 url);
......
...@@ -94,7 +94,8 @@ static i::Handle<i::BreakPoint> SetBreakPoint(v8::Local<v8::Function> fun, ...@@ -94,7 +94,8 @@ static i::Handle<i::BreakPoint> SetBreakPoint(v8::Local<v8::Function> fun,
i::Handle<i::BreakPoint> break_point = i::Handle<i::BreakPoint> break_point =
isolate->factory()->NewBreakPoint(++break_point_index, condition_string); isolate->factory()->NewBreakPoint(++break_point_index, condition_string);
debug->SetBreakPoint(function, break_point, &position); debug->SetBreakpoint(handle(function->shared(), isolate), break_point,
&position);
return break_point; return break_point;
} }
......
Debugger.setInstrumentationBreakpoint
Running test: testSetTwice
set breakpoint..
{
breakpointId : <breakpointId>
}
set breakpoint again..
{
error : {
code : -32000
message : Instrumentation breakpoint is already enabled.
}
id : <messageId>
}
remove breakpoint..
{
id : <messageId>
result : {
}
}
Running test: testScriptParsed
set breakpoint and evaluate script..
paused with reason: instrumentation
{
scriptId : <scriptId>
url : foo.js
}
set breakpoint and evaluate script with sourceMappingURL..
paused with reason: instrumentation
{
scriptId : <scriptId>
sourceMapURL : map.js
url : foo.js
}
remove breakpoint..
{
id : <messageId>
result : {
}
}
evaluate script again..
Running test: testScriptWithSourceMapParsed
set breakpoint for scriptWithSourceMapParsed..
evaluate script without sourceMappingURL..
evaluate script with sourceMappingURL..
paused with reason: instrumentation
{
scriptId : <scriptId>
sourceMapURL : map.js
url : foo.js
}
remove breakpoint..
{
id : <messageId>
result : {
}
}
evaluate script without sourceMappingURL..
evaluate script with sourceMappingURL..
Running test: testBlackboxing
set breakpoint and evaluate blackboxed script..
evaluate not blackboxed script..
paused with reason: instrumentation
{
scriptId : <scriptId>
url : bar.js
}
evaluate blackboxed script that contains not blackboxed one..
paused with reason: instrumentation
{
scriptId : <scriptId>
url : bar.js
}
Running test: testCompileFirstRunLater
set breakpoint for scriptWithSourceMapParsed..
compile script with sourceMappingURL..
evaluate script without sourceMappingURL..
run previously compiled script with sourceMappingURL..
paused with reason: instrumentation
{
scriptId : <scriptId>
sourceMapURL : boo.js
url : foo.js
}
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const { session, contextGroup, Protocol } = InspectorTest.start(
'Debugger.setInstrumentationBreakpoint');
InspectorTest.runAsyncTestSuite([
async function testSetTwice() {
await Protocol.Debugger.enable();
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
});
InspectorTest.log('set breakpoint..');
InspectorTest.logMessage(firstResult);
InspectorTest.log('set breakpoint again..');
InspectorTest.logMessage(await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
}));
InspectorTest.log('remove breakpoint..');
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: firstResult.breakpointId
}));
await Protocol.Debugger.disable();
},
async function testScriptParsed() {
await Protocol.Debugger.enable();
InspectorTest.log('set breakpoint and evaluate script..');
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
});
Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js'});
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
await Protocol.Debugger.resume();
InspectorTest.log('set breakpoint and evaluate script with sourceMappingURL..');
Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js\n//# sourceMappingURL=map.js'});
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
InspectorTest.log('remove breakpoint..');
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: firstResult.breakpointId
}));
InspectorTest.log('evaluate script again..');
await Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js'});
await Protocol.Debugger.disable();
},
async function testScriptWithSourceMapParsed() {
await Protocol.Debugger.enable();
InspectorTest.log('set breakpoint for scriptWithSourceMapParsed..');
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptWithSourceMapExecution'
});
InspectorTest.log('evaluate script without sourceMappingURL..')
await Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js'});
InspectorTest.log('evaluate script with sourceMappingURL..')
Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js\n//# sourceMappingURL=map.js'});
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
InspectorTest.log('remove breakpoint..')
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: firstResult.breakpointId
}));
InspectorTest.log('evaluate script without sourceMappingURL..')
await Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js'});
InspectorTest.log('evaluate script with sourceMappingURL..')
await Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js\n//# sourceMappingURL=map.js'});
await Protocol.Debugger.disable();
},
async function testBlackboxing() {
await Protocol.Debugger.enable();
await Protocol.Debugger.setBlackboxPatterns({patterns: ['foo\.js']});
InspectorTest.log('set breakpoint and evaluate blackboxed script..');
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
});
await Protocol.Runtime.evaluate({expression: '//# sourceURL=foo.js'});
InspectorTest.log('evaluate not blackboxed script..');
Protocol.Runtime.evaluate({expression: '//# sourceURL=bar.js'});
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
await Protocol.Debugger.resume();
InspectorTest.log('evaluate blackboxed script that contains not blackboxed one..');
Protocol.Runtime.evaluate({expression: `eval('//# sourceURL=bar.js')//# sourceURL=foo.js`});
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
await Protocol.Debugger.resume();
await Protocol.Debugger.disable();
},
async function testCompileFirstRunLater() {
await Protocol.Runtime.enable();
await Protocol.Debugger.enable();
InspectorTest.log('set breakpoint for scriptWithSourceMapParsed..');
const { result : firstResult } = await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptWithSourceMapExecution'
});
InspectorTest.log('compile script with sourceMappingURL..');
const { result: { scriptId } } = await Protocol.Runtime.compileScript({
expression: '//# sourceMappingURL=boo.js', sourceURL: 'foo.js', persistScript: true });
InspectorTest.log('evaluate script without sourceMappingURL..');
await Protocol.Runtime.evaluate({ expression: '' });
InspectorTest.log('run previously compiled script with sourceMappingURL..');
Protocol.Runtime.runScript({ scriptId });
{
const { params: { reason, data } } = await Protocol.Debugger.oncePaused();
InspectorTest.log(`paused with reason: ${reason}`);
InspectorTest.logMessage(data);
}
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
}
]);
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