summaryrefslogtreecommitdiff
path: root/deps/v8/src/inspector/v8-debugger-agent-impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/inspector/v8-debugger-agent-impl.cc')
-rw-r--r--deps/v8/src/inspector/v8-debugger-agent-impl.cc89
1 files changed, 82 insertions, 7 deletions
diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.cc b/deps/v8/src/inspector/v8-debugger-agent-impl.cc
index 9fd9e47086..3301838587 100644
--- a/deps/v8/src/inspector/v8-debugger-agent-impl.cc
+++ b/deps/v8/src/inspector/v8-debugger-agent-impl.cc
@@ -31,10 +31,13 @@ using protocol::Array;
using protocol::Maybe;
using protocol::Debugger::BreakpointId;
using protocol::Debugger::CallFrame;
+using protocol::Debugger::Scope;
using protocol::Runtime::ExceptionDetails;
-using protocol::Runtime::ScriptId;
using protocol::Runtime::RemoteObject;
-using protocol::Debugger::Scope;
+using protocol::Runtime::ScriptId;
+
+namespace InstrumentationEnum =
+ protocol::Debugger::SetInstrumentationBreakpoint::InstrumentationEnum;
namespace DebuggerAgentState {
static const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
@@ -47,6 +50,7 @@ static const char breakpointsByRegex[] = "breakpointsByRegex";
static const char breakpointsByUrl[] = "breakpointsByUrl";
static const char breakpointsByScriptHash[] = "breakpointsByScriptHash";
static const char breakpointHints[] = "breakpointHints";
+static const char instrumentationBreakpoints[] = "instrumentationBreakpoints";
} // namespace DebuggerAgentState
@@ -80,7 +84,8 @@ enum class BreakpointType {
kByScriptId,
kDebugCommand,
kMonitorCommand,
- kBreakpointAtEntry
+ kBreakpointAtEntry,
+ kInstrumentationBreakpoint
};
String16 generateBreakpointId(BreakpointType type,
@@ -106,6 +111,15 @@ String16 generateBreakpointId(BreakpointType type,
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,
String16* scriptSelector = nullptr,
int* lineNumber = nullptr, int* columnNumber = nullptr) {
@@ -114,14 +128,15 @@ bool parseBreakpointId(const String16& breakpointId, BreakpointType* type,
int rawType = breakpointId.substring(0, typeLineSeparator).toInteger();
if (rawType < static_cast<int>(BreakpointType::kByUrl) ||
- rawType > static_cast<int>(BreakpointType::kBreakpointAtEntry)) {
+ rawType > static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
return false;
}
if (type) *type = static_cast<BreakpointType>(rawType);
if (rawType == static_cast<int>(BreakpointType::kDebugCommand) ||
rawType == static_cast<int>(BreakpointType::kMonitorCommand) ||
- rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry)) {
- // The script and source position is not encoded in this case.
+ rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry) ||
+ rawType == static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
+ // The script and source position are not encoded in this case.
return true;
}
@@ -356,6 +371,7 @@ Response V8DebuggerAgentImpl::disable() {
m_state->remove(DebuggerAgentState::breakpointsByUrl);
m_state->remove(DebuggerAgentState::breakpointsByScriptHash);
m_state->remove(DebuggerAgentState::breakpointHints);
+ m_state->remove(DebuggerAgentState::instrumentationBreakpoints);
m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
v8::debug::NoBreakOnException);
@@ -506,7 +522,6 @@ Response V8DebuggerAgentImpl::setBreakpointByUrl(
break;
default:
UNREACHABLE();
- break;
}
if (breakpoints->get(breakpointId)) {
return Response::Error("Breakpoint at specified location already exists.");
@@ -580,6 +595,20 @@ Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall(
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) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled);
BreakpointType type;
@@ -606,6 +635,10 @@ Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
case BreakpointType::kByUrlRegex:
breakpoints = m_state->getObject(DebuggerAgentState::breakpointsByRegex);
break;
+ case BreakpointType::kInstrumentationBreakpoint:
+ breakpoints =
+ m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
+ break;
default:
break;
}
@@ -1496,6 +1529,40 @@ void V8DebuggerAgentImpl::didParseSource(
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(
@@ -1539,6 +1606,14 @@ void V8DebuggerAgentImpl::didPause(
std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create();
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);
if (breakpointIterator == m_debuggerBreakpointIdToBreakpointId.end()) {
continue;