| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/inspector/v8-debugger-agent-impl.h" | 5 #include "src/inspector/v8-debugger-agent-impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/debug/debug-interface.h" | 9 #include "src/debug/debug-interface.h" |
| 10 #include "src/inspector/injected-script.h" | 10 #include "src/inspector/injected-script.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 void V8DebuggerAgentImpl::enableImpl() { | 204 void V8DebuggerAgentImpl::enableImpl() { |
| 205 m_enabled = true; | 205 m_enabled = true; |
| 206 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); | 206 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); |
| 207 m_debugger->enable(); | 207 m_debugger->enable(); |
| 208 | 208 |
| 209 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts; | 209 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts; |
| 210 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); | 210 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); |
| 211 for (size_t i = 0; i < compiledScripts.size(); i++) | 211 for (size_t i = 0; i < compiledScripts.size(); i++) |
| 212 didParseSource(std::move(compiledScripts[i]), true); | 212 didParseSource(std::move(compiledScripts[i]), true); |
| 213 | 213 |
| 214 // FIXME(WK44513): breakpoints activated flag should be synchronized between | 214 m_breakpointsActive = true; |
| 215 // all front-ends | 215 m_debugger->setBreakpointsActive(true); |
| 216 m_debugger->setBreakpointsActivated(true); | |
| 217 } | 216 } |
| 218 | 217 |
| 219 bool V8DebuggerAgentImpl::enabled() { return m_enabled; } | |
| 220 | |
| 221 Response V8DebuggerAgentImpl::enable() { | 218 Response V8DebuggerAgentImpl::enable() { |
| 222 if (enabled()) return Response::OK(); | 219 if (enabled()) return Response::OK(); |
| 223 | 220 |
| 224 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) | 221 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) |
| 225 return Response::Error("Script execution is prohibited"); | 222 return Response::Error("Script execution is prohibited"); |
| 226 | 223 |
| 227 enableImpl(); | 224 enableImpl(); |
| 228 return Response::OK(); | 225 return Response::OK(); |
| 229 } | 226 } |
| 230 | 227 |
| 231 Response V8DebuggerAgentImpl::disable() { | 228 Response V8DebuggerAgentImpl::disable() { |
| 232 if (!enabled()) return Response::OK(); | 229 if (!enabled()) return Response::OK(); |
| 233 | 230 |
| 234 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, | 231 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, |
| 235 protocol::DictionaryValue::create()); | 232 protocol::DictionaryValue::create()); |
| 236 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, | 233 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, |
| 237 v8::debug::NoBreakOnException); | 234 v8::debug::NoBreakOnException); |
| 238 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); | 235 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); |
| 239 | 236 |
| 240 if (isPaused()) m_debugger->continueProgram(m_session->contextGroupId()); | 237 if (isPaused()) m_debugger->continueProgram(m_session->contextGroupId()); |
| 238 if (m_breakpointsActive) { |
| 239 m_debugger->setBreakpointsActive(false); |
| 240 m_breakpointsActive = false; |
| 241 } |
| 241 m_debugger->disable(); | 242 m_debugger->disable(); |
| 242 JavaScriptCallFrames emptyCallFrames; | 243 JavaScriptCallFrames emptyCallFrames; |
| 243 m_pausedCallFrames.swap(emptyCallFrames); | 244 m_pausedCallFrames.swap(emptyCallFrames); |
| 244 m_blackboxedPositions.clear(); | 245 m_blackboxedPositions.clear(); |
| 245 m_blackboxPattern.reset(); | 246 m_blackboxPattern.reset(); |
| 246 resetBlackboxedStateCache(); | 247 resetBlackboxedStateCache(); |
| 247 m_scripts.clear(); | 248 m_scripts.clear(); |
| 248 m_breakpointIdToDebuggerBreakpointIds.clear(); | 249 m_breakpointIdToDebuggerBreakpointIds.clear(); |
| 249 m_debugger->setAsyncCallStackDepth(this, 0); | 250 m_debugger->setAsyncCallStackDepth(this, 0); |
| 250 clearBreakDetails(); | 251 clearBreakDetails(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 279 | 280 |
| 280 String16 blackboxPattern; | 281 String16 blackboxPattern; |
| 281 if (m_state->getString(DebuggerAgentState::blackboxPattern, | 282 if (m_state->getString(DebuggerAgentState::blackboxPattern, |
| 282 &blackboxPattern)) { | 283 &blackboxPattern)) { |
| 283 setBlackboxPattern(blackboxPattern); | 284 setBlackboxPattern(blackboxPattern); |
| 284 } | 285 } |
| 285 } | 286 } |
| 286 | 287 |
| 287 Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) { | 288 Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) { |
| 288 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 289 if (!enabled()) return Response::Error(kDebuggerNotEnabled); |
| 289 // TODO(dgozman): this state should be per-session, not global per debugger. | 290 if (m_breakpointsActive == active) return Response::OK(); |
| 290 m_debugger->setBreakpointsActivated(active); | 291 m_breakpointsActive = active; |
| 292 m_debugger->setBreakpointsActive(active); |
| 291 if (!active && !m_breakReason.empty()) { | 293 if (!active && !m_breakReason.empty()) { |
| 292 clearBreakDetails(); | 294 clearBreakDetails(); |
| 293 m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId()); | 295 m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId()); |
| 294 } | 296 } |
| 295 return Response::OK(); | 297 return Response::OK(); |
| 296 } | 298 } |
| 297 | 299 |
| 298 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { | 300 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { |
| 299 m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip); | 301 m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip); |
| 300 m_skipAllPauses = skip; | 302 m_skipAllPauses = skip; |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 itStartRange, ranges.end(), | 523 itStartRange, ranges.end(), |
| 522 std::make_pair(end.GetLineNumber(), end.GetColumnNumber()), | 524 std::make_pair(end.GetLineNumber(), end.GetColumnNumber()), |
| 523 positionComparator); | 525 positionComparator); |
| 524 // Ranges array contains positions in script where blackbox state is changed. | 526 // Ranges array contains positions in script where blackbox state is changed. |
| 525 // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is | 527 // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is |
| 526 // blackboxed... | 528 // blackboxed... |
| 527 return itStartRange == itEndRange && | 529 return itStartRange == itEndRange && |
| 528 std::distance(ranges.begin(), itStartRange) % 2; | 530 std::distance(ranges.begin(), itStartRange) % 2; |
| 529 } | 531 } |
| 530 | 532 |
| 533 bool V8DebuggerAgentImpl::acceptsPause(bool isOOMBreak) const { |
| 534 return enabled() && (isOOMBreak || !m_skipAllPauses); |
| 535 } |
| 536 |
| 531 std::unique_ptr<protocol::Debugger::Location> | 537 std::unique_ptr<protocol::Debugger::Location> |
| 532 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, | 538 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, |
| 533 const ScriptBreakpoint& breakpoint, | 539 const ScriptBreakpoint& breakpoint, |
| 534 BreakpointSource source, | 540 BreakpointSource source, |
| 535 const String16& hint) { | 541 const String16& hint) { |
| 536 v8::HandleScope handles(m_isolate); | 542 v8::HandleScope handles(m_isolate); |
| 537 DCHECK(enabled()); | 543 DCHECK(enabled()); |
| 538 // FIXME: remove these checks once crbug.com/520702 is resolved. | 544 // FIXME: remove these checks once crbug.com/520702 is resolved. |
| 539 CHECK(!breakpointId.isEmpty()); | 545 CHECK(!breakpointId.isEmpty()); |
| 540 CHECK(!breakpoint.script_id.isEmpty()); | 546 CHECK(!breakpoint.script_id.isEmpty()); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 } | 682 } |
| 677 | 683 |
| 678 void V8DebuggerAgentImpl::clearBreakDetails() { | 684 void V8DebuggerAgentImpl::clearBreakDetails() { |
| 679 std::vector<BreakReason> emptyBreakReason; | 685 std::vector<BreakReason> emptyBreakReason; |
| 680 m_breakReason.swap(emptyBreakReason); | 686 m_breakReason.swap(emptyBreakReason); |
| 681 } | 687 } |
| 682 | 688 |
| 683 void V8DebuggerAgentImpl::schedulePauseOnNextStatement( | 689 void V8DebuggerAgentImpl::schedulePauseOnNextStatement( |
| 684 const String16& breakReason, | 690 const String16& breakReason, |
| 685 std::unique_ptr<protocol::DictionaryValue> data) { | 691 std::unique_ptr<protocol::DictionaryValue> data) { |
| 686 if (!enabled() || isPaused() || !m_debugger->breakpointsActivated()) return; | 692 if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return; |
| 687 if (m_breakReason.empty()) { | 693 if (m_breakReason.empty()) { |
| 688 m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId()); | 694 m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId()); |
| 689 } | 695 } |
| 690 pushBreakDetails(breakReason, std::move(data)); | 696 pushBreakDetails(breakReason, std::move(data)); |
| 691 } | 697 } |
| 692 | 698 |
| 693 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { | 699 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { |
| 694 if (!enabled() || isPaused() || !m_debugger->breakpointsActivated()) return; | 700 if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return; |
| 695 if (m_breakReason.size() == 1) { | 701 if (m_breakReason.size() == 1) { |
| 696 m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId()); | 702 m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId()); |
| 697 } | 703 } |
| 698 popBreakDetails(); | 704 popBreakDetails(); |
| 699 } | 705 } |
| 700 | 706 |
| 701 Response V8DebuggerAgentImpl::pause() { | 707 Response V8DebuggerAgentImpl::pause() { |
| 702 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 708 if (!enabled()) return Response::Error(kDebuggerNotEnabled); |
| 703 if (isPaused()) return Response::OK(); | 709 if (isPaused()) return Response::OK(); |
| 704 if (m_breakReason.empty()) { | 710 if (m_breakReason.empty()) { |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 void V8DebuggerAgentImpl::didContinue() { | 1241 void V8DebuggerAgentImpl::didContinue() { |
| 1236 JavaScriptCallFrames emptyCallFrames; | 1242 JavaScriptCallFrames emptyCallFrames; |
| 1237 m_pausedCallFrames.swap(emptyCallFrames); | 1243 m_pausedCallFrames.swap(emptyCallFrames); |
| 1238 clearBreakDetails(); | 1244 clearBreakDetails(); |
| 1239 m_frontend.resumed(); | 1245 m_frontend.resumed(); |
| 1240 } | 1246 } |
| 1241 | 1247 |
| 1242 void V8DebuggerAgentImpl::breakProgram( | 1248 void V8DebuggerAgentImpl::breakProgram( |
| 1243 const String16& breakReason, | 1249 const String16& breakReason, |
| 1244 std::unique_ptr<protocol::DictionaryValue> data) { | 1250 std::unique_ptr<protocol::DictionaryValue> data) { |
| 1245 if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return; | 1251 if (!enabled() || m_skipAllPauses || !m_debugger->canBreakProgram()) return; |
| 1246 std::vector<BreakReason> currentScheduledReason; | 1252 std::vector<BreakReason> currentScheduledReason; |
| 1247 currentScheduledReason.swap(m_breakReason); | 1253 currentScheduledReason.swap(m_breakReason); |
| 1248 pushBreakDetails(breakReason, std::move(data)); | 1254 pushBreakDetails(breakReason, std::move(data)); |
| 1249 | 1255 |
| 1250 int contextGroupId = m_session->contextGroupId(); | 1256 int contextGroupId = m_session->contextGroupId(); |
| 1251 int sessionId = m_session->sessionId(); | 1257 int sessionId = m_session->sessionId(); |
| 1252 V8InspectorImpl* inspector = m_inspector; | 1258 V8InspectorImpl* inspector = m_inspector; |
| 1253 m_debugger->breakProgram(contextGroupId); | 1259 m_debugger->breakProgram(contextGroupId); |
| 1254 // Check that session and |this| are still around. | 1260 // Check that session and |this| are still around. |
| 1255 if (!inspector->sessionById(contextGroupId, sessionId)) return; | 1261 if (!inspector->sessionById(contextGroupId, sessionId)) return; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1281 | 1287 |
| 1282 void V8DebuggerAgentImpl::reset() { | 1288 void V8DebuggerAgentImpl::reset() { |
| 1283 if (!enabled()) return; | 1289 if (!enabled()) return; |
| 1284 m_blackboxedPositions.clear(); | 1290 m_blackboxedPositions.clear(); |
| 1285 resetBlackboxedStateCache(); | 1291 resetBlackboxedStateCache(); |
| 1286 m_scripts.clear(); | 1292 m_scripts.clear(); |
| 1287 m_breakpointIdToDebuggerBreakpointIds.clear(); | 1293 m_breakpointIdToDebuggerBreakpointIds.clear(); |
| 1288 } | 1294 } |
| 1289 | 1295 |
| 1290 } // namespace v8_inspector | 1296 } // namespace v8_inspector |
| OLD | NEW |