Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1865)

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

Issue 2748503002: [inspector] changed a way of preserving stepping between tasks (Closed)
Patch Set: removed willExecuteScript from tests Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 V8DebuggerAgentImpl::V8DebuggerAgentImpl( 191 V8DebuggerAgentImpl::V8DebuggerAgentImpl(
192 V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, 192 V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
193 protocol::DictionaryValue* state) 193 protocol::DictionaryValue* state)
194 : m_inspector(session->inspector()), 194 : m_inspector(session->inspector()),
195 m_debugger(m_inspector->debugger()), 195 m_debugger(m_inspector->debugger()),
196 m_session(session), 196 m_session(session),
197 m_enabled(false), 197 m_enabled(false),
198 m_state(state), 198 m_state(state),
199 m_frontend(frontendChannel), 199 m_frontend(frontendChannel),
200 m_isolate(m_inspector->isolate()), 200 m_isolate(m_inspector->isolate()),
201 m_scheduledDebuggerStep(NoStep), 201 m_javaScriptPauseScheduled(false) {}
202 m_javaScriptPauseScheduled(false),
203 m_recursionLevelForStepOut(0) {
204 }
205 202
206 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {} 203 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {}
207 204
208 void V8DebuggerAgentImpl::enableImpl() { 205 void V8DebuggerAgentImpl::enableImpl() {
209 m_enabled = true; 206 m_enabled = true;
210 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); 207 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
211 m_debugger->enable(); 208 m_debugger->enable();
212 209
213 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts; 210 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts;
214 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); 211 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 JavaScriptCallFrames emptyCallFrames; 243 JavaScriptCallFrames emptyCallFrames;
247 m_pausedCallFrames.swap(emptyCallFrames); 244 m_pausedCallFrames.swap(emptyCallFrames);
248 m_blackboxedPositions.clear(); 245 m_blackboxedPositions.clear();
249 m_blackboxPattern.reset(); 246 m_blackboxPattern.reset();
250 resetBlackboxedStateCache(); 247 resetBlackboxedStateCache();
251 m_scripts.clear(); 248 m_scripts.clear();
252 m_breakpointIdToDebuggerBreakpointIds.clear(); 249 m_breakpointIdToDebuggerBreakpointIds.clear();
253 m_debugger->setAsyncCallStackDepth(this, 0); 250 m_debugger->setAsyncCallStackDepth(this, 0);
254 m_continueToLocationBreakpointId = String16(); 251 m_continueToLocationBreakpointId = String16();
255 clearBreakDetails(); 252 clearBreakDetails();
256 m_scheduledDebuggerStep = NoStep;
257 m_javaScriptPauseScheduled = false; 253 m_javaScriptPauseScheduled = false;
258 m_skipAllPauses = false; 254 m_skipAllPauses = false;
259 m_state->setBoolean(DebuggerAgentState::skipAllPauses, false); 255 m_state->setBoolean(DebuggerAgentState::skipAllPauses, false);
260 m_state->remove(DebuggerAgentState::blackboxPattern); 256 m_state->remove(DebuggerAgentState::blackboxPattern);
261 m_enabled = false; 257 m_enabled = false;
262 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false); 258 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
263 return Response::OK(); 259 return Response::OK();
264 } 260 }
265 261
266 void V8DebuggerAgentImpl::restore() { 262 void V8DebuggerAgentImpl::restore() {
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 } 677 }
682 678
683 void V8DebuggerAgentImpl::clearBreakDetails() { 679 void V8DebuggerAgentImpl::clearBreakDetails() {
684 std::vector<BreakReason> emptyBreakReason; 680 std::vector<BreakReason> emptyBreakReason;
685 m_breakReason.swap(emptyBreakReason); 681 m_breakReason.swap(emptyBreakReason);
686 } 682 }
687 683
688 void V8DebuggerAgentImpl::schedulePauseOnNextStatement( 684 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
689 const String16& breakReason, 685 const String16& breakReason,
690 std::unique_ptr<protocol::DictionaryValue> data) { 686 std::unique_ptr<protocol::DictionaryValue> data) {
691 if (!enabled() || m_scheduledDebuggerStep == StepInto || 687 if (!enabled() || m_javaScriptPauseScheduled || isPaused() ||
692 m_javaScriptPauseScheduled || isPaused() ||
693 !m_debugger->breakpointsActivated()) 688 !m_debugger->breakpointsActivated())
694 return; 689 return;
695 if (m_breakReason.empty()) m_debugger->setPauseOnNextStatement(true); 690 if (m_breakReason.empty()) {
691 m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId());
692 }
696 pushBreakDetails(breakReason, std::move(data)); 693 pushBreakDetails(breakReason, std::move(data));
697 } 694 }
698 695
699 void V8DebuggerAgentImpl::schedulePauseOnNextStatementIfSteppingInto() {
700 DCHECK(enabled());
701 if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled ||
702 isPaused())
703 return;
704 m_debugger->setPauseOnNextStatement(true);
705 }
706
707 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { 696 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
708 if (m_javaScriptPauseScheduled || isPaused()) return; 697 if (m_javaScriptPauseScheduled || isPaused()) return;
709 popBreakDetails(); 698 popBreakDetails();
710 if (m_breakReason.empty()) m_debugger->setPauseOnNextStatement(false); 699 if (m_breakReason.empty())
700 m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId());
711 } 701 }
712 702
713 Response V8DebuggerAgentImpl::pause() { 703 Response V8DebuggerAgentImpl::pause() {
714 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 704 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
715 if (m_javaScriptPauseScheduled || isPaused()) return Response::OK(); 705 if (m_javaScriptPauseScheduled || isPaused()) return Response::OK();
716 clearBreakDetails(); 706 clearBreakDetails();
717 m_javaScriptPauseScheduled = true; 707 m_javaScriptPauseScheduled = true;
718 m_scheduledDebuggerStep = NoStep; 708 m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId());
719 m_debugger->setPauseOnNextStatement(true);
720 return Response::OK(); 709 return Response::OK();
721 } 710 }
722 711
723 Response V8DebuggerAgentImpl::resume() { 712 Response V8DebuggerAgentImpl::resume() {
724 if (!isPaused()) return Response::Error(kDebuggerNotPaused); 713 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
725 m_scheduledDebuggerStep = NoStep;
726 m_session->releaseObjectGroup(kBacktraceObjectGroup); 714 m_session->releaseObjectGroup(kBacktraceObjectGroup);
727 m_debugger->continueProgram(); 715 m_debugger->continueProgram();
728 return Response::OK(); 716 return Response::OK();
729 } 717 }
730 718
731 Response V8DebuggerAgentImpl::stepOver() { 719 Response V8DebuggerAgentImpl::stepOver() {
732 if (!isPaused()) return Response::Error(kDebuggerNotPaused); 720 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
733 // StepOver at function return point should fallback to StepInto. 721 // StepOver at function return point should fallback to StepInto.
734 JavaScriptCallFrame* frame = 722 JavaScriptCallFrame* frame =
735 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr; 723 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr;
736 if (frame && frame->isAtReturn()) return stepInto(); 724 if (frame && frame->isAtReturn()) return stepInto();
737 m_scheduledDebuggerStep = StepOver;
738 m_session->releaseObjectGroup(kBacktraceObjectGroup); 725 m_session->releaseObjectGroup(kBacktraceObjectGroup);
739 m_debugger->stepOverStatement(); 726 m_debugger->stepOverStatement(m_session->contextGroupId());
740 return Response::OK(); 727 return Response::OK();
741 } 728 }
742 729
743 Response V8DebuggerAgentImpl::stepInto() { 730 Response V8DebuggerAgentImpl::stepInto() {
744 if (!isPaused()) return Response::Error(kDebuggerNotPaused); 731 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
745 m_scheduledDebuggerStep = StepInto;
746 m_session->releaseObjectGroup(kBacktraceObjectGroup); 732 m_session->releaseObjectGroup(kBacktraceObjectGroup);
747 m_debugger->stepIntoStatement(); 733 m_debugger->stepIntoStatement(m_session->contextGroupId());
748 return Response::OK(); 734 return Response::OK();
749 } 735 }
750 736
751 Response V8DebuggerAgentImpl::stepOut() { 737 Response V8DebuggerAgentImpl::stepOut() {
752 if (!isPaused()) return Response::Error(kDebuggerNotPaused); 738 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
753 m_scheduledDebuggerStep = StepOut;
754 m_recursionLevelForStepOut = 1;
755 m_session->releaseObjectGroup(kBacktraceObjectGroup); 739 m_session->releaseObjectGroup(kBacktraceObjectGroup);
756 m_debugger->stepOutOfFunction(); 740 m_debugger->stepOutOfFunction(m_session->contextGroupId());
757 return Response::OK(); 741 return Response::OK();
758 } 742 }
759 743
760 void V8DebuggerAgentImpl::scheduleStepIntoAsync( 744 void V8DebuggerAgentImpl::scheduleStepIntoAsync(
761 std::unique_ptr<ScheduleStepIntoAsyncCallback> callback) { 745 std::unique_ptr<ScheduleStepIntoAsyncCallback> callback) {
762 if (!isPaused()) { 746 if (!isPaused()) {
763 callback->sendFailure(Response::Error(kDebuggerNotPaused)); 747 callback->sendFailure(Response::Error(kDebuggerNotPaused));
764 return; 748 return;
765 } 749 }
766 if (m_stepIntoAsyncCallback) { 750 if (m_stepIntoAsyncCallback) {
767 m_stepIntoAsyncCallback->sendFailure(Response::Error( 751 m_stepIntoAsyncCallback->sendFailure(Response::Error(
768 "Current scheduled step into async was overriden with new one.")); 752 "Current scheduled step into async was overriden with new one."));
769 } 753 }
770 m_stepIntoAsyncCallback = std::move(callback); 754 m_stepIntoAsyncCallback = std::move(callback);
771 } 755 }
772 756
773 bool V8DebuggerAgentImpl::shouldBreakInScheduledAsyncTask() { 757 bool V8DebuggerAgentImpl::shouldBreakInScheduledAsyncTask() {
774 if (!m_stepIntoAsyncCallback) return false; 758 if (!m_stepIntoAsyncCallback) return false;
775 m_stepIntoAsyncCallback->sendSuccess(); 759 m_stepIntoAsyncCallback->sendSuccess();
776 m_stepIntoAsyncCallback.reset(); 760 m_stepIntoAsyncCallback.reset();
777 m_scheduledDebuggerStep = NoStep;
778 v8::debug::ClearStepping(m_isolate);
779 return true; 761 return true;
780 } 762 }
781 763
782 Response V8DebuggerAgentImpl::setPauseOnExceptions( 764 Response V8DebuggerAgentImpl::setPauseOnExceptions(
783 const String16& stringPauseState) { 765 const String16& stringPauseState) {
784 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 766 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
785 v8::debug::ExceptionBreakState pauseState; 767 v8::debug::ExceptionBreakState pauseState;
786 if (stringPauseState == "none") { 768 if (stringPauseState == "none") {
787 pauseState = v8::debug::NoBreakOnException; 769 pauseState = v8::debug::NoBreakOnException;
788 } else if (stringPauseState == "all") { 770 } else if (stringPauseState == "all") {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 continue; 922 continue;
941 return Response::Error( 923 return Response::Error(
942 "Input positions array is not sorted or contains duplicate values."); 924 "Input positions array is not sorted or contains duplicate values.");
943 } 925 }
944 926
945 m_blackboxedPositions[scriptId] = positions; 927 m_blackboxedPositions[scriptId] = positions;
946 it->second->resetBlackboxedStateCache(); 928 it->second->resetBlackboxedStateCache();
947 return Response::OK(); 929 return Response::OK();
948 } 930 }
949 931
950 void V8DebuggerAgentImpl::willExecuteScript(int scriptId) {
951 changeJavaScriptRecursionLevel(+1);
952 if (m_scheduledDebuggerStep != StepInto) return;
953 schedulePauseOnNextStatementIfSteppingInto();
954 }
955
956 void V8DebuggerAgentImpl::didExecuteScript() {
957 changeJavaScriptRecursionLevel(-1);
958 }
959
960 void V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) {
961 if (m_javaScriptPauseScheduled && !m_skipAllPauses && !isPaused()) {
962 // Do not ever loose user's pause request until we have actually paused.
963 m_debugger->setPauseOnNextStatement(true);
964 }
965 if (m_scheduledDebuggerStep == StepOut) {
966 m_recursionLevelForStepOut += step;
967 if (!m_recursionLevelForStepOut) {
968 // When StepOut crosses a task boundary (i.e. js -> c++) from where it was
969 // requested,
970 // switch stepping to step into a next JS task, as if we exited to a
971 // blackboxed framework.
972 m_scheduledDebuggerStep = StepInto;
973 }
974 }
975 }
976
977 Response V8DebuggerAgentImpl::currentCallFrames( 932 Response V8DebuggerAgentImpl::currentCallFrames(
978 std::unique_ptr<Array<CallFrame>>* result) { 933 std::unique_ptr<Array<CallFrame>>* result) {
979 if (!isPaused()) { 934 if (!isPaused()) {
980 *result = Array<CallFrame>::create(); 935 *result = Array<CallFrame>::create();
981 return Response::OK(); 936 return Response::OK();
982 } 937 }
983 v8::HandleScope handles(m_isolate); 938 v8::HandleScope handles(m_isolate);
984 v8::Local<v8::Context> debuggerContext = 939 v8::Local<v8::Context> debuggerContext =
985 v8::debug::GetDebugContext(m_isolate); 940 v8::debug::GetDebugContext(m_isolate);
986 v8::Context::Scope contextScope(debuggerContext); 941 v8::Context::Scope contextScope(debuggerContext);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 Response::Error("No async tasks were scheduled before pause.")); 1230 Response::Error("No async tasks were scheduled before pause."));
1276 m_stepIntoAsyncCallback.reset(); 1231 m_stepIntoAsyncCallback.reset();
1277 } 1232 }
1278 1233
1279 std::unique_ptr<Array<CallFrame>> protocolCallFrames; 1234 std::unique_ptr<Array<CallFrame>> protocolCallFrames;
1280 Response response = currentCallFrames(&protocolCallFrames); 1235 Response response = currentCallFrames(&protocolCallFrames);
1281 if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create(); 1236 if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create();
1282 m_frontend.paused(std::move(protocolCallFrames), breakReason, 1237 m_frontend.paused(std::move(protocolCallFrames), breakReason,
1283 std::move(breakAuxData), std::move(hitBreakpointIds), 1238 std::move(breakAuxData), std::move(hitBreakpointIds),
1284 currentAsyncStackTrace()); 1239 currentAsyncStackTrace());
1285 m_scheduledDebuggerStep = NoStep;
1286 m_javaScriptPauseScheduled = false; 1240 m_javaScriptPauseScheduled = false;
1287 1241
1288 if (!m_continueToLocationBreakpointId.isEmpty()) { 1242 if (!m_continueToLocationBreakpointId.isEmpty()) {
1289 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); 1243 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
1290 m_continueToLocationBreakpointId = ""; 1244 m_continueToLocationBreakpointId = "";
1291 } 1245 }
1292 } 1246 }
1293 1247
1294 void V8DebuggerAgentImpl::didContinue() { 1248 void V8DebuggerAgentImpl::didContinue() {
1295 JavaScriptCallFrames emptyCallFrames; 1249 JavaScriptCallFrames emptyCallFrames;
1296 m_pausedCallFrames.swap(emptyCallFrames); 1250 m_pausedCallFrames.swap(emptyCallFrames);
1297 clearBreakDetails(); 1251 clearBreakDetails();
1298 m_frontend.resumed(); 1252 m_frontend.resumed();
1299 } 1253 }
1300 1254
1301 void V8DebuggerAgentImpl::breakProgram( 1255 void V8DebuggerAgentImpl::breakProgram(
1302 const String16& breakReason, 1256 const String16& breakReason,
1303 std::unique_ptr<protocol::DictionaryValue> data) { 1257 std::unique_ptr<protocol::DictionaryValue> data) {
1304 if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return; 1258 if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return;
1305 std::vector<BreakReason> currentScheduledReason; 1259 std::vector<BreakReason> currentScheduledReason;
1306 currentScheduledReason.swap(m_breakReason); 1260 currentScheduledReason.swap(m_breakReason);
1307 pushBreakDetails(breakReason, std::move(data)); 1261 pushBreakDetails(breakReason, std::move(data));
1308 m_scheduledDebuggerStep = NoStep;
1309 m_debugger->breakProgram(); 1262 m_debugger->breakProgram();
1310 popBreakDetails(); 1263 popBreakDetails();
1311 m_breakReason.swap(currentScheduledReason); 1264 m_breakReason.swap(currentScheduledReason);
1312 if (!m_breakReason.empty()) { 1265 if (!m_breakReason.empty()) {
1313 m_debugger->setPauseOnNextStatement(true); 1266 m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId());
1314 } 1267 }
1315 } 1268 }
1316 1269
1317 void V8DebuggerAgentImpl::breakProgramOnException( 1270 void V8DebuggerAgentImpl::breakProgramOnException(
1318 const String16& breakReason, 1271 const String16& breakReason,
1319 std::unique_ptr<protocol::DictionaryValue> data) { 1272 std::unique_ptr<protocol::DictionaryValue> data) {
1320 if (!enabled() || 1273 if (!enabled() ||
1321 m_debugger->getPauseOnExceptionsState() == v8::debug::NoBreakOnException) 1274 m_debugger->getPauseOnExceptionsState() == v8::debug::NoBreakOnException)
1322 return; 1275 return;
1323 breakProgram(breakReason, std::move(data)); 1276 breakProgram(breakReason, std::move(data));
(...skipping 11 matching lines...) Expand all
1335 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, 1288 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId,
1336 int lineNumber, int columnNumber, 1289 int lineNumber, int columnNumber,
1337 BreakpointSource source) { 1290 BreakpointSource source) {
1338 removeBreakpointImpl(generateBreakpointId( 1291 removeBreakpointImpl(generateBreakpointId(
1339 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), 1292 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()),
1340 source)); 1293 source));
1341 } 1294 }
1342 1295
1343 void V8DebuggerAgentImpl::reset() { 1296 void V8DebuggerAgentImpl::reset() {
1344 if (!enabled()) return; 1297 if (!enabled()) return;
1345 m_scheduledDebuggerStep = NoStep;
1346 m_blackboxedPositions.clear(); 1298 m_blackboxedPositions.clear();
1347 resetBlackboxedStateCache(); 1299 resetBlackboxedStateCache();
1348 m_scripts.clear(); 1300 m_scripts.clear();
1349 m_breakpointIdToDebuggerBreakpointIds.clear(); 1301 m_breakpointIdToDebuggerBreakpointIds.clear();
1350 } 1302 }
1351 1303
1352 } // namespace v8_inspector 1304 } // namespace v8_inspector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698