| Index: src/inspector/v8-debugger-agent-impl.cc
|
| diff --git a/src/inspector/v8-debugger-agent-impl.cc b/src/inspector/v8-debugger-agent-impl.cc
|
| index 7de46a1787818170d3e91cd0902a0b2f977ecfcf..b33238e21869e512210b4872784a4e31de09edc5 100644
|
| --- a/src/inspector/v8-debugger-agent-impl.cc
|
| +++ b/src/inspector/v8-debugger-agent-impl.cc
|
| @@ -175,6 +175,12 @@ Response V8DebuggerAgentImpl::disable() {
|
| m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0);
|
|
|
| if (isPaused()) m_debugger->continueProgram();
|
| +
|
| + {
|
| + v8::HandleScope scope(m_isolate);
|
| + for (const auto& it : m_idToBreakpoints) removeBreakpointImpl(it.first);
|
| + }
|
| +
|
| m_debugger->disable();
|
| JavaScriptCallFrames emptyCallFrames;
|
| m_pausedCallFrames.swap(emptyCallFrames);
|
| @@ -182,9 +188,10 @@ Response V8DebuggerAgentImpl::disable() {
|
| m_blackboxPattern.reset();
|
| resetBlackboxedStateCache();
|
| m_scripts.clear();
|
| - m_breakpointIdToDebuggerBreakpointIds.clear();
|
| + m_idToBreakpoints.clear();
|
| + m_breakpointIdToSource.clear();
|
| m_debugger->setAsyncCallStackDepth(this, 0);
|
| - m_continueToLocationBreakpointId = String16();
|
| + m_continueToLocationBreakpoint.Reset();
|
| clearBreakDetails();
|
| m_scheduledDebuggerStep = NoStep;
|
| m_javaScriptPauseScheduled = false;
|
| @@ -321,8 +328,7 @@ Response V8DebuggerAgentImpl::setBreakpoint(
|
|
|
| String16 breakpointId =
|
| generateBreakpointId(breakpoint, UserBreakpointSource);
|
| - if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
|
| - m_breakpointIdToDebuggerBreakpointIds.end()) {
|
| + if (m_idToBreakpoints.find(breakpointId) != m_idToBreakpoints.end()) {
|
| return Response::Error("Breakpoint at specified location already exists.");
|
| }
|
| *actualLocation =
|
| @@ -343,20 +349,14 @@ Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
|
|
|
| void V8DebuggerAgentImpl::removeBreakpointImpl(const String16& breakpointId) {
|
| DCHECK(enabled());
|
| - BreakpointIdToDebuggerBreakpointIdsMap::iterator
|
| - debuggerBreakpointIdsIterator =
|
| - m_breakpointIdToDebuggerBreakpointIds.find(breakpointId);
|
| - if (debuggerBreakpointIdsIterator ==
|
| - m_breakpointIdToDebuggerBreakpointIds.end())
|
| - return;
|
| - const std::vector<String16>& ids = debuggerBreakpointIdsIterator->second;
|
| - for (size_t i = 0; i < ids.size(); ++i) {
|
| - const String16& debuggerBreakpointId = ids[i];
|
| -
|
| - m_debugger->removeBreakpoint(debuggerBreakpointId);
|
| - m_serverBreakpoints.erase(debuggerBreakpointId);
|
| + auto it = m_idToBreakpoints.find(breakpointId);
|
| + if (it == m_idToBreakpoints.end()) return;
|
| + v8::HandleScope scope(m_isolate);
|
| + for (const auto& breakpoint : it->second) {
|
| + v8::debug::ClearBreakPoint(m_isolate, breakpoint.Get(m_isolate));
|
| }
|
| - m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId);
|
| + m_breakpointIdToSource.erase(it->first);
|
| + m_idToBreakpoints.erase(it);
|
| }
|
|
|
| Response V8DebuggerAgentImpl::getPossibleBreakpoints(
|
| @@ -404,17 +404,27 @@ Response V8DebuggerAgentImpl::getPossibleBreakpoints(
|
| Response V8DebuggerAgentImpl::continueToLocation(
|
| std::unique_ptr<protocol::Debugger::Location> location) {
|
| if (!enabled()) return Response::Error(kDebuggerNotEnabled);
|
| - if (!m_continueToLocationBreakpointId.isEmpty()) {
|
| - m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
|
| - m_continueToLocationBreakpointId = "";
|
| + ScriptsMap::iterator it = m_scripts.find(location->getScriptId());
|
| + if (it == m_scripts.end()) {
|
| + return Response::Error("No script with given id found");
|
| }
|
|
|
| - ScriptBreakpoint breakpoint(location->getScriptId(),
|
| - location->getLineNumber(),
|
| - location->getColumnNumber(0), String16());
|
| + v8::HandleScope handle_scope(m_isolate);
|
|
|
| - m_continueToLocationBreakpointId = m_debugger->setBreakpoint(
|
| - breakpoint, &breakpoint.line_number, &breakpoint.column_number);
|
| + if (!m_continueToLocationBreakpoint.IsEmpty()) {
|
| + v8::debug::ClearBreakPoint(m_isolate,
|
| + m_continueToLocationBreakpoint.Get(m_isolate));
|
| + m_continueToLocationBreakpoint.Reset();
|
| + }
|
| +
|
| + v8::debug::Location position(location->getLineNumber(),
|
| + location->getColumnNumber(0));
|
| + v8::Local<v8::debug::BreakPoint> breakPoint = v8::debug::BreakPoint::New(
|
| + m_isolate, v8::String::Empty(m_isolate), v8::Undefined(m_isolate));
|
| +
|
| + v8::debug::Location result = it->second->setBreakpoint(position, breakPoint);
|
| + if (result.IsEmpty()) return Response::Error("Could not resolve breakpoint");
|
| + m_continueToLocationBreakpoint.Reset(m_isolate, breakPoint);
|
| // TODO(kozyatinskiy): Return actual line and column number.
|
| return resume();
|
| }
|
| @@ -474,22 +484,26 @@ V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId,
|
| &translatedBreakpoint.script_id, &translatedBreakpoint.line_number,
|
| &translatedBreakpoint.column_number);
|
|
|
| - int actualLineNumber;
|
| - int actualColumnNumber;
|
| - String16 debuggerBreakpointId = m_debugger->setBreakpoint(
|
| - translatedBreakpoint, &actualLineNumber, &actualColumnNumber);
|
| - if (debuggerBreakpointId.isEmpty()) return nullptr;
|
| + v8::Local<v8::String> condition = toV8String(m_isolate, breakpoint.condition);
|
| + v8::Local<v8::Value> v8BreakpointId = toV8String(m_isolate, breakpointId);
|
| + v8::Local<v8::debug::BreakPoint> breakPoint =
|
| + v8::debug::BreakPoint::New(m_isolate, condition, v8BreakpointId);
|
| + v8::debug::Location position(translatedBreakpoint.line_number,
|
| + translatedBreakpoint.column_number);
|
| + v8::debug::Location result =
|
| + scriptIterator->second->setBreakpoint(position, breakPoint);
|
| + if (result.IsEmpty()) return nullptr;
|
| +
|
| + int actualLineNumber = result.GetLineNumber();
|
| + int actualColumnNumber = result.GetColumnNumber();
|
|
|
| // Translate back from v8 location to protocol location for the return value.
|
| m_debugger->wasmTranslation()->TranslateWasmScriptLocationToProtocolLocation(
|
| &translatedBreakpoint.script_id, &actualLineNumber, &actualColumnNumber);
|
|
|
| - m_serverBreakpoints[debuggerBreakpointId] =
|
| - std::make_pair(breakpointId, source);
|
| CHECK(!breakpointId.isEmpty());
|
| -
|
| - m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
|
| - debuggerBreakpointId);
|
| + m_idToBreakpoints[breakpointId].emplace_back(m_isolate, breakPoint);
|
| + m_breakpointIdToSource[breakpointId] = source;
|
| return buildProtocolLocation(translatedBreakpoint.script_id, actualLineNumber,
|
| actualColumnNumber);
|
| }
|
| @@ -1075,11 +1089,10 @@ void V8DebuggerAgentImpl::didParseSource(
|
| }
|
| }
|
|
|
| -void V8DebuggerAgentImpl::didPause(int contextId,
|
| - v8::Local<v8::Value> exception,
|
| - const std::vector<String16>& hitBreakpoints,
|
| - bool isPromiseRejection, bool isUncaught,
|
| - bool isOOMBreak) {
|
| +void V8DebuggerAgentImpl::didPause(
|
| + int contextId, v8::Local<v8::Value> exception,
|
| + const v8::PersistentValueVector<v8::debug::BreakPoint>& hitBreakpoints,
|
| + bool isPromiseRejection, bool isUncaught, bool isOOMBreak) {
|
| JavaScriptCallFrames frames = m_debugger->currentCallFrames();
|
| m_pausedCallFrames.swap(frames);
|
| v8::HandleScope handles(m_isolate);
|
| @@ -1115,20 +1128,17 @@ void V8DebuggerAgentImpl::didPause(int contextId,
|
| std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create();
|
|
|
| bool hasDebugCommandBreakpointReason = false;
|
| - for (const auto& point : hitBreakpoints) {
|
| - DebugServerBreakpointToBreakpointIdAndSourceMap::iterator
|
| - breakpointIterator = m_serverBreakpoints.find(point);
|
| - if (breakpointIterator != m_serverBreakpoints.end()) {
|
| - const String16& localId = breakpointIterator->second.first;
|
| - hitBreakpointIds->addItem(localId);
|
| -
|
| - BreakpointSource source = breakpointIterator->second.second;
|
| - if (!hasDebugCommandBreakpointReason &&
|
| - source == DebugCommandBreakpointSource) {
|
| - hasDebugCommandBreakpointReason = true;
|
| - hitReasons.push_back(std::make_pair(
|
| - protocol::Debugger::Paused::ReasonEnum::DebugCommand, nullptr));
|
| - }
|
| + for (size_t i = 0; i < hitBreakpoints.Size(); ++i) {
|
| + String16 id = toProtocolStringWithTypeCheck(hitBreakpoints.Get(i)->Data());
|
| + if (id.isEmpty()) continue;
|
| + auto it = m_breakpointIdToSource.find(id);
|
| + if (it == m_breakpointIdToSource.end()) continue;
|
| + hitBreakpointIds->addItem(it->first);
|
| + if (!hasDebugCommandBreakpointReason &&
|
| + it->second == DebugCommandBreakpointSource) {
|
| + hasDebugCommandBreakpointReason = true;
|
| + hitReasons.push_back(std::make_pair(
|
| + protocol::Debugger::Paused::ReasonEnum::DebugCommand, nullptr));
|
| }
|
| }
|
|
|
| @@ -1150,8 +1160,9 @@ void V8DebuggerAgentImpl::didPause(int contextId,
|
| std::unique_ptr<protocol::DictionaryValue> reason =
|
| protocol::DictionaryValue::create();
|
| reason->setString("reason", hitReasons[i].first);
|
| - if (hitReasons[i].second)
|
| + if (hitReasons[i].second) {
|
| reason->setObject("auxData", std::move(hitReasons[i].second));
|
| + }
|
| reasons->pushValue(std::move(reason));
|
| }
|
| breakAuxData = protocol::DictionaryValue::create();
|
| @@ -1167,9 +1178,10 @@ void V8DebuggerAgentImpl::didPause(int contextId,
|
| m_scheduledDebuggerStep = NoStep;
|
| m_javaScriptPauseScheduled = false;
|
|
|
| - if (!m_continueToLocationBreakpointId.isEmpty()) {
|
| - m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
|
| - m_continueToLocationBreakpointId = "";
|
| + if (!m_continueToLocationBreakpoint.IsEmpty()) {
|
| + v8::debug::ClearBreakPoint(m_isolate,
|
| + m_continueToLocationBreakpoint.Get(m_isolate));
|
| + m_continueToLocationBreakpoint.Reset();
|
| }
|
| }
|
|
|
| @@ -1225,7 +1237,8 @@ void V8DebuggerAgentImpl::reset() {
|
| m_blackboxedPositions.clear();
|
| resetBlackboxedStateCache();
|
| m_scripts.clear();
|
| - m_breakpointIdToDebuggerBreakpointIds.clear();
|
| + m_idToBreakpoints.clear();
|
| + m_breakpointIdToSource.clear();
|
| }
|
|
|
| } // namespace v8_inspector
|
|
|