Chromium Code Reviews

Side by Side Diff: src/inspector/v8-debugger-agent-impl.cc

Issue 2668763003: [inspector] V8DebuggerAgent cleanup (Closed)
Patch Set: better test Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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 116 matching lines...)
127 : m_inspector(session->inspector()), 127 : m_inspector(session->inspector()),
128 m_debugger(m_inspector->debugger()), 128 m_debugger(m_inspector->debugger()),
129 m_session(session), 129 m_session(session),
130 m_enabled(false), 130 m_enabled(false),
131 m_state(state), 131 m_state(state),
132 m_frontend(frontendChannel), 132 m_frontend(frontendChannel),
133 m_isolate(m_inspector->isolate()), 133 m_isolate(m_inspector->isolate()),
134 m_breakReason(protocol::Debugger::Paused::ReasonEnum::Other), 134 m_breakReason(protocol::Debugger::Paused::ReasonEnum::Other),
135 m_scheduledDebuggerStep(NoStep), 135 m_scheduledDebuggerStep(NoStep),
136 m_javaScriptPauseScheduled(false), 136 m_javaScriptPauseScheduled(false),
137 m_recursionLevelForStepOut(0), 137 m_recursionLevelForStepOut(0) {
138 m_skipAllPauses(false) {
139 clearBreakDetails(); 138 clearBreakDetails();
140 } 139 }
141 140
142 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {} 141 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {}
143 142
144 void V8DebuggerAgentImpl::enableImpl() { 143 void V8DebuggerAgentImpl::enableImpl() {
145 // m_inspector->addListener may result in reporting all parsed scripts to
146 // the agent so it should already be in enabled state by then.
147 m_enabled = true; 144 m_enabled = true;
148 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); 145 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
149 m_debugger->enable(); 146 m_debugger->enable();
150 147
151 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts; 148 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts;
152 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); 149 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts);
153 for (size_t i = 0; i < compiledScripts.size(); i++) 150 for (size_t i = 0; i < compiledScripts.size(); i++)
154 didParseSource(std::move(compiledScripts[i]), true); 151 didParseSource(std::move(compiledScripts[i]), true);
155 152
156 // FIXME(WK44513): breakpoints activated flag should be synchronized between 153 // FIXME(WK44513): breakpoints activated flag should be synchronized between
(...skipping 15 matching lines...)
172 169
173 Response V8DebuggerAgentImpl::disable() { 170 Response V8DebuggerAgentImpl::disable() {
174 if (!enabled()) return Response::OK(); 171 if (!enabled()) return Response::OK();
175 172
176 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, 173 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints,
177 protocol::DictionaryValue::create()); 174 protocol::DictionaryValue::create());
178 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, 175 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
179 v8::debug::NoBreakOnException); 176 v8::debug::NoBreakOnException);
180 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); 177 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0);
181 178
182 if (!m_pausedContext.IsEmpty()) m_debugger->continueProgram(); 179 if (isPaused()) m_debugger->continueProgram();
183 m_debugger->disable(); 180 m_debugger->disable();
184 m_pausedContext.Reset();
185 JavaScriptCallFrames emptyCallFrames; 181 JavaScriptCallFrames emptyCallFrames;
186 m_pausedCallFrames.swap(emptyCallFrames); 182 m_pausedCallFrames.swap(emptyCallFrames);
187 m_blackboxedPositions.clear(); 183 m_blackboxedPositions.clear();
188 m_blackboxPattern.reset(); 184 m_blackboxPattern.reset();
189 resetBlackboxedStateCache(); 185 resetBlackboxedStateCache();
190 m_scripts.clear(); 186 m_scripts.clear();
191 m_breakpointIdToDebuggerBreakpointIds.clear(); 187 m_breakpointIdToDebuggerBreakpointIds.clear();
192 m_debugger->setAsyncCallStackDepth(this, 0); 188 m_debugger->setAsyncCallStackDepth(this, 0);
193 m_continueToLocationBreakpointId = String16(); 189 m_continueToLocationBreakpointId = String16();
194 clearBreakDetails(); 190 clearBreakDetails();
195 m_scheduledDebuggerStep = NoStep; 191 m_scheduledDebuggerStep = NoStep;
196 m_javaScriptPauseScheduled = false; 192 m_javaScriptPauseScheduled = false;
197 m_skipAllPauses = false;
198 m_state->remove(DebuggerAgentState::blackboxPattern); 193 m_state->remove(DebuggerAgentState::blackboxPattern);
199 m_enabled = false; 194 m_enabled = false;
200 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false); 195 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
201 return Response::OK(); 196 return Response::OK();
202 } 197 }
203 198
204 void V8DebuggerAgentImpl::restore() { 199 void V8DebuggerAgentImpl::restore() {
205 DCHECK(!m_enabled); 200 DCHECK(!m_enabled);
206 if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false)) 201 if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false))
207 return; 202 return;
208 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) 203 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
209 return; 204 return;
210 205
211 enableImpl(); 206 enableImpl();
212 207
213 int pauseState = v8::debug::NoBreakOnException; 208 int pauseState = v8::debug::NoBreakOnException;
214 m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState); 209 m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
215 setPauseOnExceptionsImpl(pauseState); 210 setPauseOnExceptionsImpl(pauseState);
216 211
217 m_skipAllPauses =
218 m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
219
220 int asyncCallStackDepth = 0; 212 int asyncCallStackDepth = 0;
221 m_state->getInteger(DebuggerAgentState::asyncCallStackDepth, 213 m_state->getInteger(DebuggerAgentState::asyncCallStackDepth,
222 &asyncCallStackDepth); 214 &asyncCallStackDepth);
223 m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth); 215 m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth);
224 216
225 String16 blackboxPattern; 217 String16 blackboxPattern;
226 if (m_state->getString(DebuggerAgentState::blackboxPattern, 218 if (m_state->getString(DebuggerAgentState::blackboxPattern,
227 &blackboxPattern)) { 219 &blackboxPattern)) {
228 setBlackboxPattern(blackboxPattern); 220 setBlackboxPattern(blackboxPattern);
229 } 221 }
230 } 222 }
231 223
232 Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) { 224 Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) {
233 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 225 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
234 m_debugger->setBreakpointsActivated(active); 226 m_debugger->setBreakpointsActivated(active);
235 return Response::OK(); 227 return Response::OK();
236 } 228 }
237 229
238 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { 230 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) {
239 m_skipAllPauses = skip; 231 m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip);
240 m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
241 return Response::OK(); 232 return Response::OK();
242 } 233 }
243 234
235 bool V8DebuggerAgentImpl::skipAllPauses() const {
236 bool value = false;
237 return m_state->getBoolean(DebuggerAgentState::skipAllPauses, &value) &&
dgozman 2017/02/02 23:40:36 Let's have m_skipAllPauses, as this is slow but me
kozy 2017/02/03 01:04:08 Done.
238 value;
239 }
240
244 static std::unique_ptr<protocol::DictionaryValue> 241 static std::unique_ptr<protocol::DictionaryValue>
245 buildObjectForBreakpointCookie(const String16& url, int lineNumber, 242 buildObjectForBreakpointCookie(const String16& url, int lineNumber,
246 int columnNumber, const String16& condition, 243 int columnNumber, const String16& condition,
247 bool isRegex) { 244 bool isRegex) {
248 std::unique_ptr<protocol::DictionaryValue> breakpointObject = 245 std::unique_ptr<protocol::DictionaryValue> breakpointObject =
249 protocol::DictionaryValue::create(); 246 protocol::DictionaryValue::create();
250 breakpointObject->setString(DebuggerAgentState::url, url); 247 breakpointObject->setString(DebuggerAgentState::url, url);
251 breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); 248 breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber);
252 breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); 249 breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber);
253 breakpointObject->setString(DebuggerAgentState::condition, condition); 250 breakpointObject->setString(DebuggerAgentState::condition, condition);
(...skipping 287 matching lines...)
541 if (!response.isSuccess()) return response; 538 if (!response.isSuccess()) return response;
542 *newCallFrames = std::move(callFrames); 539 *newCallFrames = std::move(callFrames);
543 *asyncStackTrace = currentAsyncStackTrace(); 540 *asyncStackTrace = currentAsyncStackTrace();
544 return Response::OK(); 541 return Response::OK();
545 } 542 }
546 543
547 Response V8DebuggerAgentImpl::restartFrame( 544 Response V8DebuggerAgentImpl::restartFrame(
548 const String16& callFrameId, 545 const String16& callFrameId,
549 std::unique_ptr<Array<CallFrame>>* newCallFrames, 546 std::unique_ptr<Array<CallFrame>>* newCallFrames,
550 Maybe<StackTrace>* asyncStackTrace) { 547 Maybe<StackTrace>* asyncStackTrace) {
551 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 548 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
552 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 549 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
553 callFrameId); 550 callFrameId);
554 Response response = scope.initialize(); 551 Response response = scope.initialize();
555 if (!response.isSuccess()) return response; 552 if (!response.isSuccess()) return response;
556 if (scope.frameOrdinal() >= m_pausedCallFrames.size()) 553 if (scope.frameOrdinal() >= m_pausedCallFrames.size())
557 return Response::Error("Could not find call frame with given id"); 554 return Response::Error("Could not find call frame with given id");
558 555
559 v8::Local<v8::Value> resultValue; 556 v8::Local<v8::Value> resultValue;
560 v8::Local<v8::Boolean> result; 557 v8::Local<v8::Boolean> result;
561 if (!m_pausedCallFrames[scope.frameOrdinal()]->restart().ToLocal( 558 if (!m_pausedCallFrames[scope.frameOrdinal()]->restart().ToLocal(
(...skipping 20 matching lines...)
582 return Response::Error("No script for id: " + scriptId); 579 return Response::Error("No script for id: " + scriptId);
583 v8::HandleScope handles(m_isolate); 580 v8::HandleScope handles(m_isolate);
584 *scriptSource = it->second->source(m_isolate); 581 *scriptSource = it->second->source(m_isolate);
585 return Response::OK(); 582 return Response::OK();
586 } 583 }
587 584
588 void V8DebuggerAgentImpl::schedulePauseOnNextStatement( 585 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
589 const String16& breakReason, 586 const String16& breakReason,
590 std::unique_ptr<protocol::DictionaryValue> data) { 587 std::unique_ptr<protocol::DictionaryValue> data) {
591 if (!enabled() || m_scheduledDebuggerStep == StepInto || 588 if (!enabled() || m_scheduledDebuggerStep == StepInto ||
592 m_javaScriptPauseScheduled || m_debugger->isPaused() || 589 m_javaScriptPauseScheduled || isPaused() ||
593 !m_debugger->breakpointsActivated()) 590 !m_debugger->breakpointsActivated())
594 return; 591 return;
595 m_breakReason = breakReason; 592 m_breakReason = breakReason;
596 m_breakAuxData = std::move(data); 593 m_breakAuxData = std::move(data);
597 m_debugger->setPauseOnNextStatement(true); 594 m_debugger->setPauseOnNextStatement(true);
598 } 595 }
599 596
600 void V8DebuggerAgentImpl::schedulePauseOnNextStatementIfSteppingInto() { 597 void V8DebuggerAgentImpl::schedulePauseOnNextStatementIfSteppingInto() {
601 DCHECK(enabled()); 598 DCHECK(enabled());
602 if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled || 599 if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled ||
603 m_debugger->isPaused()) 600 isPaused())
604 return; 601 return;
605 clearBreakDetails(); 602 clearBreakDetails();
606 m_debugger->setPauseOnNextStatement(true); 603 m_debugger->setPauseOnNextStatement(true);
607 } 604 }
608 605
609 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { 606 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
610 if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return; 607 if (m_javaScriptPauseScheduled || isPaused()) return;
611 clearBreakDetails(); 608 clearBreakDetails();
612 m_debugger->setPauseOnNextStatement(false); 609 m_debugger->setPauseOnNextStatement(false);
613 } 610 }
614 611
615 Response V8DebuggerAgentImpl::pause() { 612 Response V8DebuggerAgentImpl::pause() {
616 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 613 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
617 if (m_javaScriptPauseScheduled || m_debugger->isPaused()) 614 if (m_javaScriptPauseScheduled || isPaused()) return Response::OK();
dgozman 2017/02/02 23:40:36 Let's merge V8Debugger::isPaused() with m_runningN
kozy 2017/02/03 01:04:08 Done.
618 return Response::OK();
619 clearBreakDetails(); 615 clearBreakDetails();
620 m_javaScriptPauseScheduled = true; 616 m_javaScriptPauseScheduled = true;
621 m_scheduledDebuggerStep = NoStep; 617 m_scheduledDebuggerStep = NoStep;
622 m_debugger->setPauseOnNextStatement(true); 618 m_debugger->setPauseOnNextStatement(true);
623 return Response::OK(); 619 return Response::OK();
624 } 620 }
625 621
626 Response V8DebuggerAgentImpl::resume() { 622 Response V8DebuggerAgentImpl::resume() {
627 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 623 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
628 m_scheduledDebuggerStep = NoStep; 624 m_scheduledDebuggerStep = NoStep;
629 m_session->releaseObjectGroup(kBacktraceObjectGroup); 625 m_session->releaseObjectGroup(kBacktraceObjectGroup);
630 m_debugger->continueProgram(); 626 m_debugger->continueProgram();
631 return Response::OK(); 627 return Response::OK();
632 } 628 }
633 629
634 Response V8DebuggerAgentImpl::stepOver() { 630 Response V8DebuggerAgentImpl::stepOver() {
635 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 631 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
636 // StepOver at function return point should fallback to StepInto. 632 // StepOver at function return point should fallback to StepInto.
637 JavaScriptCallFrame* frame = 633 JavaScriptCallFrame* frame =
638 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr; 634 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr;
639 if (frame && frame->isAtReturn()) return stepInto(); 635 if (frame && frame->isAtReturn()) {
636 return stepInto();
dgozman 2017/02/02 23:40:36 Please undo.
kozy 2017/02/03 01:04:08 Done.
637 }
640 m_scheduledDebuggerStep = StepOver; 638 m_scheduledDebuggerStep = StepOver;
641 m_session->releaseObjectGroup(kBacktraceObjectGroup); 639 m_session->releaseObjectGroup(kBacktraceObjectGroup);
642 m_debugger->stepOverStatement(); 640 m_debugger->stepOverStatement();
643 return Response::OK(); 641 return Response::OK();
644 } 642 }
645 643
646 Response V8DebuggerAgentImpl::stepInto() { 644 Response V8DebuggerAgentImpl::stepInto() {
647 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 645 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
648 m_scheduledDebuggerStep = StepInto; 646 m_scheduledDebuggerStep = StepInto;
649 m_session->releaseObjectGroup(kBacktraceObjectGroup); 647 m_session->releaseObjectGroup(kBacktraceObjectGroup);
650 m_debugger->stepIntoStatement(); 648 m_debugger->stepIntoStatement();
651 return Response::OK(); 649 return Response::OK();
652 } 650 }
653 651
654 Response V8DebuggerAgentImpl::stepOut() { 652 Response V8DebuggerAgentImpl::stepOut() {
655 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 653 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
656 m_scheduledDebuggerStep = StepOut; 654 m_scheduledDebuggerStep = StepOut;
657 m_recursionLevelForStepOut = 1; 655 m_recursionLevelForStepOut = 1;
658 m_session->releaseObjectGroup(kBacktraceObjectGroup); 656 m_session->releaseObjectGroup(kBacktraceObjectGroup);
659 m_debugger->stepOutOfFunction(); 657 m_debugger->stepOutOfFunction();
660 return Response::OK(); 658 return Response::OK();
661 } 659 }
662 660
663 Response V8DebuggerAgentImpl::setPauseOnExceptions( 661 Response V8DebuggerAgentImpl::setPauseOnExceptions(
664 const String16& stringPauseState) { 662 const String16& stringPauseState) {
665 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 663 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
(...skipping 17 matching lines...)
683 static_cast<v8::debug::ExceptionBreakState>(pauseState)); 681 static_cast<v8::debug::ExceptionBreakState>(pauseState));
684 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState); 682 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState);
685 } 683 }
686 684
687 Response V8DebuggerAgentImpl::evaluateOnCallFrame( 685 Response V8DebuggerAgentImpl::evaluateOnCallFrame(
688 const String16& callFrameId, const String16& expression, 686 const String16& callFrameId, const String16& expression,
689 Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI, 687 Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
690 Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview, 688 Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
691 std::unique_ptr<RemoteObject>* result, 689 std::unique_ptr<RemoteObject>* result,
692 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { 690 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
693 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 691 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
694 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 692 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
695 callFrameId); 693 callFrameId);
696 Response response = scope.initialize(); 694 Response response = scope.initialize();
697 if (!response.isSuccess()) return response; 695 if (!response.isSuccess()) return response;
698 if (scope.frameOrdinal() >= m_pausedCallFrames.size()) 696 if (scope.frameOrdinal() >= m_pausedCallFrames.size())
699 return Response::Error("Could not find call frame with given id"); 697 return Response::Error("Could not find call frame with given id");
700 698
701 if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI(); 699 if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
702 if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); 700 if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole();
703 701
704 v8::MaybeLocal<v8::Value> maybeResultValue = 702 v8::MaybeLocal<v8::Value> maybeResultValue =
705 m_pausedCallFrames[scope.frameOrdinal()]->evaluate( 703 m_pausedCallFrames[scope.frameOrdinal()]->evaluate(
706 toV8String(m_isolate, expression)); 704 toV8String(m_isolate, expression));
707 705
708 // Re-initialize after running client's code, as it could have destroyed 706 // Re-initialize after running client's code, as it could have destroyed
709 // context or session. 707 // context or session.
710 response = scope.initialize(); 708 response = scope.initialize();
711 if (!response.isSuccess()) return response; 709 if (!response.isSuccess()) return response;
712 return scope.injectedScript()->wrapEvaluateResult( 710 return scope.injectedScript()->wrapEvaluateResult(
713 maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), 711 maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""),
714 returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result, 712 returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result,
715 exceptionDetails); 713 exceptionDetails);
716 } 714 }
717 715
718 Response V8DebuggerAgentImpl::setVariableValue( 716 Response V8DebuggerAgentImpl::setVariableValue(
719 int scopeNumber, const String16& variableName, 717 int scopeNumber, const String16& variableName,
720 std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument, 718 std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument,
721 const String16& callFrameId) { 719 const String16& callFrameId) {
722 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 720 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
723 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused); 721 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
724 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 722 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
725 callFrameId); 723 callFrameId);
726 Response response = scope.initialize(); 724 Response response = scope.initialize();
727 if (!response.isSuccess()) return response; 725 if (!response.isSuccess()) return response;
728 v8::Local<v8::Value> newValue; 726 v8::Local<v8::Value> newValue;
729 response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(), 727 response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(),
730 &newValue); 728 &newValue);
731 if (!response.isSuccess()) return response; 729 if (!response.isSuccess()) return response;
732 730
733 if (scope.frameOrdinal() >= m_pausedCallFrames.size()) 731 if (scope.frameOrdinal() >= m_pausedCallFrames.size())
(...skipping 88 matching lines...)
822 "Input positions array is not sorted or contains duplicate values."); 820 "Input positions array is not sorted or contains duplicate values.");
823 } 821 }
824 822
825 m_blackboxedPositions[scriptId] = positions; 823 m_blackboxedPositions[scriptId] = positions;
826 it->second->resetBlackboxedStateCache(); 824 it->second->resetBlackboxedStateCache();
827 return Response::OK(); 825 return Response::OK();
828 } 826 }
829 827
830 void V8DebuggerAgentImpl::willExecuteScript(int scriptId) { 828 void V8DebuggerAgentImpl::willExecuteScript(int scriptId) {
831 changeJavaScriptRecursionLevel(+1); 829 changeJavaScriptRecursionLevel(+1);
832 // Fast return.
833 if (m_scheduledDebuggerStep != StepInto) return; 830 if (m_scheduledDebuggerStep != StepInto) return;
834 schedulePauseOnNextStatementIfSteppingInto(); 831 schedulePauseOnNextStatementIfSteppingInto();
835 } 832 }
836 833
837 void V8DebuggerAgentImpl::didExecuteScript() { 834 void V8DebuggerAgentImpl::didExecuteScript() {
838 changeJavaScriptRecursionLevel(-1); 835 changeJavaScriptRecursionLevel(-1);
839 } 836 }
840 837
841 void V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) { 838 void V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) {
842 if (m_javaScriptPauseScheduled && !m_skipAllPauses && 839 if (m_javaScriptPauseScheduled && !isPaused()) {
843 !m_debugger->isPaused()) {
844 // Do not ever loose user's pause request until we have actually paused. 840 // Do not ever loose user's pause request until we have actually paused.
845 m_debugger->setPauseOnNextStatement(true); 841 m_debugger->setPauseOnNextStatement(true);
846 } 842 }
847 if (m_scheduledDebuggerStep == StepOut) { 843 if (m_scheduledDebuggerStep == StepOut) {
848 m_recursionLevelForStepOut += step; 844 m_recursionLevelForStepOut += step;
849 if (!m_recursionLevelForStepOut) { 845 if (!m_recursionLevelForStepOut) {
850 // When StepOut crosses a task boundary (i.e. js -> c++) from where it was 846 // When StepOut crosses a task boundary (i.e. js -> c++) from where it was
851 // requested, 847 // requested,
852 // switch stepping to step into a next JS task, as if we exited to a 848 // switch stepping to step into a next JS task, as if we exited to a
853 // blackboxed framework. 849 // blackboxed framework.
854 m_scheduledDebuggerStep = StepInto; 850 m_scheduledDebuggerStep = StepInto;
855 } 851 }
856 } 852 }
857 } 853 }
858 854
859 Response V8DebuggerAgentImpl::currentCallFrames( 855 Response V8DebuggerAgentImpl::currentCallFrames(
860 std::unique_ptr<Array<CallFrame>>* result) { 856 std::unique_ptr<Array<CallFrame>>* result) {
861 if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) { 857 if (!isPaused()) {
862 *result = Array<CallFrame>::create(); 858 *result = Array<CallFrame>::create();
863 return Response::OK(); 859 return Response::OK();
864 } 860 }
865 v8::HandleScope handles(m_isolate); 861 v8::HandleScope handles(m_isolate);
866 v8::Local<v8::Context> debuggerContext = 862 v8::Local<v8::Context> debuggerContext =
867 v8::debug::GetDebugContext(m_isolate); 863 v8::debug::GetDebugContext(m_isolate);
868 v8::Context::Scope contextScope(debuggerContext); 864 v8::Context::Scope contextScope(debuggerContext);
869 865
870 v8::Local<v8::Array> objects = v8::Array::New(m_isolate); 866 v8::Local<v8::Array> objects = v8::Array::New(m_isolate);
871 867
(...skipping 88 matching lines...)
960 if (!response.isSuccess()) return response; 956 if (!response.isSuccess()) return response;
961 protocol::ErrorSupport errorSupport; 957 protocol::ErrorSupport errorSupport;
962 *result = Array<CallFrame>::fromValue(protocolValue.get(), &errorSupport); 958 *result = Array<CallFrame>::fromValue(protocolValue.get(), &errorSupport);
963 if (!*result) return Response::Error(errorSupport.errors()); 959 if (!*result) return Response::Error(errorSupport.errors());
964 TranslateWasmStackTraceLocations(result->get(), 960 TranslateWasmStackTraceLocations(result->get(),
965 m_debugger->wasmTranslation()); 961 m_debugger->wasmTranslation());
966 return Response::OK(); 962 return Response::OK();
967 } 963 }
968 964
969 std::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() { 965 std::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() {
970 if (m_pausedContext.IsEmpty()) return nullptr; 966 if (!isPaused()) return nullptr;
971 V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain(); 967 V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain();
972 return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger) 968 return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger)
973 : nullptr; 969 : nullptr;
974 } 970 }
975 971
976 void V8DebuggerAgentImpl::didParseSource( 972 void V8DebuggerAgentImpl::didParseSource(
977 std::unique_ptr<V8DebuggerScript> script, bool success) { 973 std::unique_ptr<V8DebuggerScript> script, bool success) {
978 v8::HandleScope handles(m_isolate); 974 v8::HandleScope handles(m_isolate);
979 String16 scriptSource = script->source(m_isolate); 975 String16 scriptSource = script->source(m_isolate);
980 if (!success) script->setSourceURL(findSourceURL(scriptSource, false)); 976 if (!success) script->setSourceURL(findSourceURL(scriptSource, false));
(...skipping 68 matching lines...)
1049 &breakpoint.column_number); 1045 &breakpoint.column_number);
1050 breakpointObject->getString(DebuggerAgentState::condition, 1046 breakpointObject->getString(DebuggerAgentState::condition,
1051 &breakpoint.condition); 1047 &breakpoint.condition);
1052 std::unique_ptr<protocol::Debugger::Location> location = 1048 std::unique_ptr<protocol::Debugger::Location> location =
1053 resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource); 1049 resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource);
1054 if (location) 1050 if (location)
1055 m_frontend.breakpointResolved(cookie.first, std::move(location)); 1051 m_frontend.breakpointResolved(cookie.first, std::move(location));
1056 } 1052 }
1057 } 1053 }
1058 1054
1059 bool V8DebuggerAgentImpl::didPause(v8::Local<v8::Context> context, 1055 void V8DebuggerAgentImpl::didPause(int contextId,
1060 v8::Local<v8::Value> exception, 1056 v8::Local<v8::Value> exception,
1061 const std::vector<String16>& hitBreakpoints, 1057 const std::vector<String16>& hitBreakpoints,
1062 bool isPromiseRejection, bool isUncaught, 1058 bool isPromiseRejection, bool isUncaught,
1063 bool isOOMBreak) { 1059 bool isOOMBreak) {
1064 if (!isOOMBreak) { 1060 DCHECK(!isPaused());
1065 if (m_skipAllPauses) return false;
1066 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1);
1067 JavaScriptCallFrame* topCallFrame =
1068 !callFrames.empty() ? callFrames.begin()->get() : nullptr;
1069 // Skip pauses inside V8 internal scripts and on syntax errors.
1070 if (!topCallFrame) return false;
1071 }
1072 DCHECK(m_pausedContext.IsEmpty());
1073 JavaScriptCallFrames frames = m_debugger->currentCallFrames(); 1061 JavaScriptCallFrames frames = m_debugger->currentCallFrames();
1074 m_pausedCallFrames.swap(frames); 1062 m_pausedCallFrames.swap(frames);
1075 m_pausedContext.Reset(m_isolate, context);
1076 v8::HandleScope handles(m_isolate); 1063 v8::HandleScope handles(m_isolate);
1077 1064
1078 if (isOOMBreak) { 1065 if (isOOMBreak) {
1079 m_breakReason = protocol::Debugger::Paused::ReasonEnum::OOM; 1066 m_breakReason = protocol::Debugger::Paused::ReasonEnum::OOM;
1080 m_breakAuxData = nullptr; 1067 m_breakAuxData = nullptr;
1081 } else if (!exception.IsEmpty()) { 1068 } else if (!exception.IsEmpty()) {
1082 InjectedScript* injectedScript = nullptr; 1069 InjectedScript* injectedScript = nullptr;
1083 m_session->findInjectedScript(InspectedContext::contextId(context), 1070 m_session->findInjectedScript(contextId, injectedScript);
1084 injectedScript);
1085 if (injectedScript) { 1071 if (injectedScript) {
1086 m_breakReason = 1072 m_breakReason =
1087 isPromiseRejection 1073 isPromiseRejection
1088 ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection 1074 ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
1089 : protocol::Debugger::Paused::ReasonEnum::Exception; 1075 : protocol::Debugger::Paused::ReasonEnum::Exception;
1090 std::unique_ptr<protocol::Runtime::RemoteObject> obj; 1076 std::unique_ptr<protocol::Runtime::RemoteObject> obj;
1091 injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false, 1077 injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false,
1092 &obj); 1078 &obj);
1093 if (obj) { 1079 if (obj) {
1094 m_breakAuxData = obj->toValue(); 1080 m_breakAuxData = obj->toValue();
(...skipping 27 matching lines...)
1122 m_frontend.paused(std::move(protocolCallFrames), m_breakReason, 1108 m_frontend.paused(std::move(protocolCallFrames), m_breakReason,
1123 std::move(m_breakAuxData), std::move(hitBreakpointIds), 1109 std::move(m_breakAuxData), std::move(hitBreakpointIds),
1124 currentAsyncStackTrace()); 1110 currentAsyncStackTrace());
1125 m_scheduledDebuggerStep = NoStep; 1111 m_scheduledDebuggerStep = NoStep;
1126 m_javaScriptPauseScheduled = false; 1112 m_javaScriptPauseScheduled = false;
1127 1113
1128 if (!m_continueToLocationBreakpointId.isEmpty()) { 1114 if (!m_continueToLocationBreakpointId.isEmpty()) {
1129 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); 1115 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
1130 m_continueToLocationBreakpointId = ""; 1116 m_continueToLocationBreakpointId = "";
1131 } 1117 }
1132 return true;
1133 } 1118 }
1134 1119
1135 void V8DebuggerAgentImpl::didContinue() { 1120 void V8DebuggerAgentImpl::didContinue() {
1136 m_pausedContext.Reset();
1137 JavaScriptCallFrames emptyCallFrames; 1121 JavaScriptCallFrames emptyCallFrames;
1138 m_pausedCallFrames.swap(emptyCallFrames); 1122 m_pausedCallFrames.swap(emptyCallFrames);
1139 clearBreakDetails(); 1123 clearBreakDetails();
1140 m_frontend.resumed(); 1124 m_frontend.resumed();
1141 } 1125 }
1142 1126
1143 void V8DebuggerAgentImpl::breakProgram( 1127 void V8DebuggerAgentImpl::breakProgram(
1144 const String16& breakReason, 1128 const String16& breakReason,
1145 std::unique_ptr<protocol::DictionaryValue> data) { 1129 std::unique_ptr<protocol::DictionaryValue> data) {
1146 if (!enabled() || m_skipAllPauses || !m_pausedContext.IsEmpty() || 1130 if (!enabled() || !m_debugger->canBreakProgram()) return;
dgozman 2017/02/02 23:40:36 Check for skipAllPauses.
kozy 2017/02/03 01:04:08 Done.
1147 !m_debugger->canBreakProgram())
1148 return;
1149 m_breakReason = breakReason; 1131 m_breakReason = breakReason;
1150 m_breakAuxData = std::move(data); 1132 m_breakAuxData = std::move(data);
1151 m_scheduledDebuggerStep = NoStep; 1133 m_scheduledDebuggerStep = NoStep;
1152 m_debugger->breakProgram(); 1134 m_debugger->breakProgram();
1153 } 1135 }
1154 1136
1155 void V8DebuggerAgentImpl::breakProgramOnException( 1137 void V8DebuggerAgentImpl::breakProgramOnException(
1156 const String16& breakReason, 1138 const String16& breakReason,
1157 std::unique_ptr<protocol::DictionaryValue> data) { 1139 std::unique_ptr<protocol::DictionaryValue> data) {
1158 if (!enabled() || 1140 if (!enabled() ||
(...skipping 27 matching lines...)
1186 void V8DebuggerAgentImpl::reset() { 1168 void V8DebuggerAgentImpl::reset() {
1187 if (!enabled()) return; 1169 if (!enabled()) return;
1188 m_scheduledDebuggerStep = NoStep; 1170 m_scheduledDebuggerStep = NoStep;
1189 m_blackboxedPositions.clear(); 1171 m_blackboxedPositions.clear();
1190 resetBlackboxedStateCache(); 1172 resetBlackboxedStateCache();
1191 m_scripts.clear(); 1173 m_scripts.clear();
1192 m_breakpointIdToDebuggerBreakpointIds.clear(); 1174 m_breakpointIdToDebuggerBreakpointIds.clear();
1193 } 1175 }
1194 1176
1195 } // namespace v8_inspector 1177 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger-agent-impl.h ('k') | test/inspector/debugger/step-into-next-script.js » ('j') | no next file with comments »

Powered by Google App Engine