diff options
Diffstat (limited to 'deps/v8/src/inspector/v8-debugger-agent-impl.cc')
-rw-r--r-- | deps/v8/src/inspector/v8-debugger-agent-impl.cc | 89 |
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; |