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

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: rebased on tunned stepping at return 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
« no previous file with comments | « src/inspector/v8-debugger-agent-impl.h ('k') | src/inspector/v8-inspector-impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
734 JavaScriptCallFrame* frame =
735 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr;
736 if (frame && frame->isAtReturn()) return stepInto();
737 m_scheduledDebuggerStep = StepOver;
738 m_session->releaseObjectGroup(kBacktraceObjectGroup); 721 m_session->releaseObjectGroup(kBacktraceObjectGroup);
739 m_debugger->stepOverStatement(); 722 m_debugger->stepOverStatement(m_session->contextGroupId());
740 return Response::OK(); 723 return Response::OK();
741 } 724 }
742 725
743 Response V8DebuggerAgentImpl::stepInto() { 726 Response V8DebuggerAgentImpl::stepInto() {
744 if (!isPaused()) return Response::Error(kDebuggerNotPaused); 727 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
745 m_scheduledDebuggerStep = StepInto;
746 m_session->releaseObjectGroup(kBacktraceObjectGroup); 728 m_session->releaseObjectGroup(kBacktraceObjectGroup);
747 m_debugger->stepIntoStatement(); 729 m_debugger->stepIntoStatement(m_session->contextGroupId());
748 return Response::OK(); 730 return Response::OK();
749 } 731 }
750 732
751 Response V8DebuggerAgentImpl::stepOut() { 733 Response V8DebuggerAgentImpl::stepOut() {
752 if (!isPaused()) return Response::Error(kDebuggerNotPaused); 734 if (!isPaused()) return Response::Error(kDebuggerNotPaused);
753 m_scheduledDebuggerStep = StepOut;
754 m_recursionLevelForStepOut = 1;
755 m_session->releaseObjectGroup(kBacktraceObjectGroup); 735 m_session->releaseObjectGroup(kBacktraceObjectGroup);
756 m_debugger->stepOutOfFunction(); 736 m_debugger->stepOutOfFunction(m_session->contextGroupId());
757 return Response::OK(); 737 return Response::OK();
758 } 738 }
759 739
760 void V8DebuggerAgentImpl::scheduleStepIntoAsync( 740 void V8DebuggerAgentImpl::scheduleStepIntoAsync(
761 std::unique_ptr<ScheduleStepIntoAsyncCallback> callback) { 741 std::unique_ptr<ScheduleStepIntoAsyncCallback> callback) {
762 if (!isPaused()) { 742 if (!isPaused()) {
763 callback->sendFailure(Response::Error(kDebuggerNotPaused)); 743 callback->sendFailure(Response::Error(kDebuggerNotPaused));
764 return; 744 return;
765 } 745 }
766 if (m_stepIntoAsyncCallback) { 746 if (m_stepIntoAsyncCallback) {
767 m_stepIntoAsyncCallback->sendFailure(Response::Error( 747 m_stepIntoAsyncCallback->sendFailure(Response::Error(
768 "Current scheduled step into async was overriden with new one.")); 748 "Current scheduled step into async was overriden with new one."));
769 } 749 }
770 m_stepIntoAsyncCallback = std::move(callback); 750 m_stepIntoAsyncCallback = std::move(callback);
771 } 751 }
772 752
773 bool V8DebuggerAgentImpl::shouldBreakInScheduledAsyncTask() { 753 bool V8DebuggerAgentImpl::shouldBreakInScheduledAsyncTask() {
774 if (!m_stepIntoAsyncCallback) return false; 754 if (!m_stepIntoAsyncCallback) return false;
775 m_stepIntoAsyncCallback->sendSuccess(); 755 m_stepIntoAsyncCallback->sendSuccess();
776 m_stepIntoAsyncCallback.reset(); 756 m_stepIntoAsyncCallback.reset();
777 m_scheduledDebuggerStep = NoStep;
778 v8::debug::ClearStepping(m_isolate);
779 return true; 757 return true;
780 } 758 }
781 759
782 Response V8DebuggerAgentImpl::setPauseOnExceptions( 760 Response V8DebuggerAgentImpl::setPauseOnExceptions(
783 const String16& stringPauseState) { 761 const String16& stringPauseState) {
784 if (!enabled()) return Response::Error(kDebuggerNotEnabled); 762 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
785 v8::debug::ExceptionBreakState pauseState; 763 v8::debug::ExceptionBreakState pauseState;
786 if (stringPauseState == "none") { 764 if (stringPauseState == "none") {
787 pauseState = v8::debug::NoBreakOnException; 765 pauseState = v8::debug::NoBreakOnException;
788 } else if (stringPauseState == "all") { 766 } else if (stringPauseState == "all") {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 continue; 918 continue;
941 return Response::Error( 919 return Response::Error(
942 "Input positions array is not sorted or contains duplicate values."); 920 "Input positions array is not sorted or contains duplicate values.");
943 } 921 }
944 922
945 m_blackboxedPositions[scriptId] = positions; 923 m_blackboxedPositions[scriptId] = positions;
946 it->second->resetBlackboxedStateCache(); 924 it->second->resetBlackboxedStateCache();
947 return Response::OK(); 925 return Response::OK();
948 } 926 }
949 927
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( 928 Response V8DebuggerAgentImpl::currentCallFrames(
978 std::unique_ptr<Array<CallFrame>>* result) { 929 std::unique_ptr<Array<CallFrame>>* result) {
979 if (!isPaused()) { 930 if (!isPaused()) {
980 *result = Array<CallFrame>::create(); 931 *result = Array<CallFrame>::create();
981 return Response::OK(); 932 return Response::OK();
982 } 933 }
983 v8::HandleScope handles(m_isolate); 934 v8::HandleScope handles(m_isolate);
984 v8::Local<v8::Context> debuggerContext = 935 v8::Local<v8::Context> debuggerContext =
985 v8::debug::GetDebugContext(m_isolate); 936 v8::debug::GetDebugContext(m_isolate);
986 v8::Context::Scope contextScope(debuggerContext); 937 v8::Context::Scope contextScope(debuggerContext);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 Response::Error("No async tasks were scheduled before pause.")); 1231 Response::Error("No async tasks were scheduled before pause."));
1281 m_stepIntoAsyncCallback.reset(); 1232 m_stepIntoAsyncCallback.reset();
1282 } 1233 }
1283 1234
1284 std::unique_ptr<Array<CallFrame>> protocolCallFrames; 1235 std::unique_ptr<Array<CallFrame>> protocolCallFrames;
1285 Response response = currentCallFrames(&protocolCallFrames); 1236 Response response = currentCallFrames(&protocolCallFrames);
1286 if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create(); 1237 if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create();
1287 m_frontend.paused(std::move(protocolCallFrames), breakReason, 1238 m_frontend.paused(std::move(protocolCallFrames), breakReason,
1288 std::move(breakAuxData), std::move(hitBreakpointIds), 1239 std::move(breakAuxData), std::move(hitBreakpointIds),
1289 currentAsyncStackTrace()); 1240 currentAsyncStackTrace());
1290 m_scheduledDebuggerStep = NoStep;
1291 m_javaScriptPauseScheduled = false; 1241 m_javaScriptPauseScheduled = false;
1292 1242
1293 if (!m_continueToLocationBreakpointId.isEmpty()) { 1243 if (!m_continueToLocationBreakpointId.isEmpty()) {
1294 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); 1244 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
1295 m_continueToLocationBreakpointId = ""; 1245 m_continueToLocationBreakpointId = "";
1296 } 1246 }
1297 } 1247 }
1298 1248
1299 void V8DebuggerAgentImpl::didContinue() { 1249 void V8DebuggerAgentImpl::didContinue() {
1300 JavaScriptCallFrames emptyCallFrames; 1250 JavaScriptCallFrames emptyCallFrames;
1301 m_pausedCallFrames.swap(emptyCallFrames); 1251 m_pausedCallFrames.swap(emptyCallFrames);
1302 clearBreakDetails(); 1252 clearBreakDetails();
1303 m_frontend.resumed(); 1253 m_frontend.resumed();
1304 } 1254 }
1305 1255
1306 void V8DebuggerAgentImpl::breakProgram( 1256 void V8DebuggerAgentImpl::breakProgram(
1307 const String16& breakReason, 1257 const String16& breakReason,
1308 std::unique_ptr<protocol::DictionaryValue> data) { 1258 std::unique_ptr<protocol::DictionaryValue> data) {
1309 if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return; 1259 if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return;
1310 std::vector<BreakReason> currentScheduledReason; 1260 std::vector<BreakReason> currentScheduledReason;
1311 currentScheduledReason.swap(m_breakReason); 1261 currentScheduledReason.swap(m_breakReason);
1312 pushBreakDetails(breakReason, std::move(data)); 1262 pushBreakDetails(breakReason, std::move(data));
1313 m_scheduledDebuggerStep = NoStep;
1314 m_debugger->breakProgram(); 1263 m_debugger->breakProgram();
1315 popBreakDetails(); 1264 popBreakDetails();
1316 m_breakReason.swap(currentScheduledReason); 1265 m_breakReason.swap(currentScheduledReason);
1317 if (!m_breakReason.empty()) { 1266 if (!m_breakReason.empty()) {
1318 m_debugger->setPauseOnNextStatement(true); 1267 m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId());
1319 } 1268 }
1320 } 1269 }
1321 1270
1322 void V8DebuggerAgentImpl::breakProgramOnException( 1271 void V8DebuggerAgentImpl::breakProgramOnException(
1323 const String16& breakReason, 1272 const String16& breakReason,
1324 std::unique_ptr<protocol::DictionaryValue> data) { 1273 std::unique_ptr<protocol::DictionaryValue> data) {
1325 if (!enabled() || 1274 if (!enabled() ||
1326 m_debugger->getPauseOnExceptionsState() == v8::debug::NoBreakOnException) 1275 m_debugger->getPauseOnExceptionsState() == v8::debug::NoBreakOnException)
1327 return; 1276 return;
1328 breakProgram(breakReason, std::move(data)); 1277 breakProgram(breakReason, std::move(data));
(...skipping 11 matching lines...) Expand all
1340 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, 1289 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId,
1341 int lineNumber, int columnNumber, 1290 int lineNumber, int columnNumber,
1342 BreakpointSource source) { 1291 BreakpointSource source) {
1343 removeBreakpointImpl(generateBreakpointId( 1292 removeBreakpointImpl(generateBreakpointId(
1344 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), 1293 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()),
1345 source)); 1294 source));
1346 } 1295 }
1347 1296
1348 void V8DebuggerAgentImpl::reset() { 1297 void V8DebuggerAgentImpl::reset() {
1349 if (!enabled()) return; 1298 if (!enabled()) return;
1350 m_scheduledDebuggerStep = NoStep;
1351 m_blackboxedPositions.clear(); 1299 m_blackboxedPositions.clear();
1352 resetBlackboxedStateCache(); 1300 resetBlackboxedStateCache();
1353 m_scripts.clear(); 1301 m_scripts.clear();
1354 m_breakpointIdToDebuggerBreakpointIds.clear(); 1302 m_breakpointIdToDebuggerBreakpointIds.clear();
1355 } 1303 }
1356 1304
1357 } // namespace v8_inspector 1305 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger-agent-impl.h ('k') | src/inspector/v8-inspector-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698