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

Side by Side Diff: Source/core/inspector/InspectorDebuggerAgent.cpp

Issue 309013005: DevTools: Event listener breakpoint should not stop if happened inside framework. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: addressed Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/inspector/InspectorDebuggerAgent.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 static const char lineNumber[] = "lineNumber"; 69 static const char lineNumber[] = "lineNumber";
70 static const char columnNumber[] = "columnNumber"; 70 static const char columnNumber[] = "columnNumber";
71 static const char condition[] = "condition"; 71 static const char condition[] = "condition";
72 static const char isAnti[] = "isAnti"; 72 static const char isAnti[] = "isAnti";
73 static const char skipStackPattern[] = "skipStackPattern"; 73 static const char skipStackPattern[] = "skipStackPattern";
74 static const char skipAllPauses[] = "skipAllPauses"; 74 static const char skipAllPauses[] = "skipAllPauses";
75 static const char skipAllPausesExpiresOnReload[] = "skipAllPausesExpiresOnReload "; 75 static const char skipAllPausesExpiresOnReload[] = "skipAllPausesExpiresOnReload ";
76 76
77 }; 77 };
78 78
79 static const int numberOfStepsBeforeStepOut = 20; 79 static const int maxSkipStepInCount = 20;
80 80
81 const char InspectorDebuggerAgent::backtraceObjectGroup[] = "backtrace"; 81 const char InspectorDebuggerAgent::backtraceObjectGroup[] = "backtrace";
82 82
83 static String breakpointIdSuffix(InspectorDebuggerAgent::BreakpointSource source ) 83 static String breakpointIdSuffix(InspectorDebuggerAgent::BreakpointSource source )
84 { 84 {
85 switch (source) { 85 switch (source) {
86 case InspectorDebuggerAgent::UserBreakpointSource: 86 case InspectorDebuggerAgent::UserBreakpointSource:
87 break; 87 break;
88 case InspectorDebuggerAgent::DebugCommandBreakpointSource: 88 case InspectorDebuggerAgent::DebugCommandBreakpointSource:
89 return ":debug"; 89 return ":debug";
90 case InspectorDebuggerAgent::MonitorCommandBreakpointSource: 90 case InspectorDebuggerAgent::MonitorCommandBreakpointSource:
91 return ":monitor"; 91 return ":monitor";
92 } 92 }
93 return String(); 93 return String();
94 } 94 }
95 95
96 static String generateBreakpointId(const String& scriptId, int lineNumber, int c olumnNumber, InspectorDebuggerAgent::BreakpointSource source) 96 static String generateBreakpointId(const String& scriptId, int lineNumber, int c olumnNumber, InspectorDebuggerAgent::BreakpointSource source)
97 { 97 {
98 return scriptId + ':' + String::number(lineNumber) + ':' + String::number(co lumnNumber) + breakpointIdSuffix(source); 98 return scriptId + ':' + String::number(lineNumber) + ':' + String::number(co lumnNumber) + breakpointIdSuffix(source);
99 } 99 }
100 100
101 InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedSc riptManager) 101 InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedSc riptManager)
102 : InspectorBaseAgent<InspectorDebuggerAgent>("Debugger") 102 : InspectorBaseAgent<InspectorDebuggerAgent>("Debugger")
103 , m_injectedScriptManager(injectedScriptManager) 103 , m_injectedScriptManager(injectedScriptManager)
104 , m_frontend(0) 104 , m_frontend(0)
105 , m_pausedScriptState(nullptr) 105 , m_pausedScriptState(nullptr)
106 , m_javaScriptPauseScheduled(false) 106 , m_javaScriptPauseScheduled(false)
107 , m_debuggerStepScheduled(false) 107 , m_debuggerStepScheduled(false)
108 , m_pausingOnNativeEvent(false)
108 , m_listener(0) 109 , m_listener(0)
109 , m_skipStepInCount(numberOfStepsBeforeStepOut) 110 , m_skippedStepInCount(0)
110 , m_skipAllPauses(false) 111 , m_skipAllPauses(false)
111 { 112 {
112 } 113 }
113 114
114 InspectorDebuggerAgent::~InspectorDebuggerAgent() 115 InspectorDebuggerAgent::~InspectorDebuggerAgent()
115 { 116 {
116 ASSERT(!m_instrumentingAgents->inspectorDebuggerAgent()); 117 ASSERT(!m_instrumentingAgents->inspectorDebuggerAgent());
117 } 118 }
118 119
119 void InspectorDebuggerAgent::init() 120 void InspectorDebuggerAgent::init()
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 return ScriptDebugListener::NoSkip; 523 return ScriptDebugListener::NoSkip;
523 } 524 }
524 525
525 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPaus e() 526 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPaus e()
526 { 527 {
527 if (!m_cachedSkipStackRegExp) 528 if (!m_cachedSkipStackRegExp)
528 return ScriptDebugListener::NoSkip; 529 return ScriptDebugListener::NoSkip;
529 530
530 RefPtr<JavaScriptCallFrame> topFrame = scriptDebugServer().topCallFrameNoSco pes(); 531 RefPtr<JavaScriptCallFrame> topFrame = scriptDebugServer().topCallFrameNoSco pes();
531 String scriptUrl = scriptURL(topFrame.get()); 532 String scriptUrl = scriptURL(topFrame.get());
532 if (!scriptUrl.isEmpty() && m_cachedSkipStackRegExp->match(scriptUrl) != -1) { 533 if (scriptUrl.isEmpty() || m_cachedSkipStackRegExp->match(scriptUrl) == -1)
533 if (m_skipStepInCount > 0) { 534 return ScriptDebugListener::NoSkip;
534 --m_skipStepInCount; 535
535 return ScriptDebugListener::StepInto; 536 if (m_skippedStepInCount == 0) {
537 m_minFrameCountForSkip = scriptDebugServer().frameCount();
538 m_skippedStepInCount = 1;
539 return ScriptDebugListener::StepInto;
540 }
541
542 if (m_skippedStepInCount < maxSkipStepInCount && topFrame->isAtReturn() && s criptDebugServer().frameCount() <= m_minFrameCountForSkip)
543 m_skippedStepInCount = maxSkipStepInCount;
544
545 if (m_skippedStepInCount >= maxSkipStepInCount) {
546 if (m_pausingOnNativeEvent) {
547 m_pausingOnNativeEvent = false;
548 m_skippedStepInCount = 0;
549 return ScriptDebugListener::Continue;
536 } 550 }
537 return ScriptDebugListener::StepOut; 551 return ScriptDebugListener::StepOut;
538 } 552 }
539 return ScriptDebugListener::NoSkip; 553
554 ++m_skippedStepInCount;
555 return ScriptDebugListener::StepInto;
540 } 556 }
541 557
542 PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreak point(const String& breakpointId, const String& scriptId, const ScriptBreakpoint & breakpoint, BreakpointSource source) 558 PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreak point(const String& breakpointId, const String& scriptId, const ScriptBreakpoint & breakpoint, BreakpointSource source)
543 { 559 {
544 ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); 560 ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
545 if (scriptIterator == m_scripts.end()) 561 if (scriptIterator == m_scripts.end())
546 return nullptr; 562 return nullptr;
547 Script& script = scriptIterator->value; 563 Script& script = scriptIterator->value;
548 if (breakpoint.lineNumber < script.startLine || script.endLine < breakpoint. lineNumber) 564 if (breakpoint.lineNumber < script.startLine || script.endLine < breakpoint. lineNumber)
549 return nullptr; 565 return nullptr;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForOb jectId(functionId); 638 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForOb jectId(functionId);
623 if (injectedScript.isEmpty()) { 639 if (injectedScript.isEmpty()) {
624 *errorString = "Function object id is obsolete"; 640 *errorString = "Function object id is obsolete";
625 return; 641 return;
626 } 642 }
627 injectedScript.getFunctionDetails(errorString, functionId, &details); 643 injectedScript.getFunctionDetails(errorString, functionId, &details);
628 } 644 }
629 645
630 void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Deb ugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data) 646 void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Deb ugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data)
631 { 647 {
632 if (m_javaScriptPauseScheduled) 648 if (m_javaScriptPauseScheduled || isPaused())
633 return; 649 return;
634 m_breakReason = breakReason; 650 m_breakReason = breakReason;
635 m_breakAuxData = data; 651 m_breakAuxData = data;
636 m_debuggerStepScheduled = true; 652 m_pausingOnNativeEvent = true;
637 scriptDebugServer().setPauseOnNextStatement(true); 653 scriptDebugServer().setPauseOnNextStatement(true);
638 } 654 }
639 655
640 void InspectorDebuggerAgent::cancelPauseOnNextStatement() 656 void InspectorDebuggerAgent::cancelPauseOnNextStatement()
641 { 657 {
642 if (m_javaScriptPauseScheduled) 658 if (m_javaScriptPauseScheduled || isPaused())
643 return; 659 return;
644 clearBreakDetails(); 660 clearBreakDetails();
645 m_debuggerStepScheduled = false; 661 m_pausingOnNativeEvent = false;
646 scriptDebugServer().setPauseOnNextStatement(false); 662 scriptDebugServer().setPauseOnNextStatement(false);
647 } 663 }
648 664
649 void InspectorDebuggerAgent::didInstallTimer(ExecutionContext* context, int time rId, int timeout, bool singleShot) 665 void InspectorDebuggerAgent::didInstallTimer(ExecutionContext* context, int time rId, int timeout, bool singleShot)
650 { 666 {
651 if (m_asyncCallStackTracker.isEnabled()) 667 if (m_asyncCallStackTracker.isEnabled())
652 m_asyncCallStackTracker.didInstallTimer(context, timerId, singleShot, sc riptDebugServer().currentCallFramesForAsyncStack()); 668 m_asyncCallStackTracker.didInstallTimer(context, timerId, singleShot, sc riptDebugServer().currentCallFramesForAsyncStack());
653 } 669 }
654 670
655 void InspectorDebuggerAgent::didRemoveTimer(ExecutionContext* context, int timer Id) 671 void InspectorDebuggerAgent::didRemoveTimer(ExecutionContext* context, int timer Id)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 } 751 }
736 752
737 void InspectorDebuggerAgent::didDeliverMutationRecords() 753 void InspectorDebuggerAgent::didDeliverMutationRecords()
738 { 754 {
739 if (m_asyncCallStackTracker.isEnabled()) 755 if (m_asyncCallStackTracker.isEnabled())
740 m_asyncCallStackTracker.didFireAsyncCall(); 756 m_asyncCallStackTracker.didFireAsyncCall();
741 } 757 }
742 758
743 void InspectorDebuggerAgent::pause(ErrorString*) 759 void InspectorDebuggerAgent::pause(ErrorString*)
744 { 760 {
745 if (m_javaScriptPauseScheduled) 761 if (m_javaScriptPauseScheduled || isPaused())
746 return; 762 return;
747 clearBreakDetails(); 763 clearBreakDetails();
748 m_javaScriptPauseScheduled = true; 764 m_javaScriptPauseScheduled = true;
749 m_debuggerStepScheduled = false;
750 scriptDebugServer().setPauseOnNextStatement(true); 765 scriptDebugServer().setPauseOnNextStatement(true);
751 } 766 }
752 767
753 void InspectorDebuggerAgent::resume(ErrorString* errorString) 768 void InspectorDebuggerAgent::resume(ErrorString* errorString)
754 { 769 {
755 if (!assertPaused(errorString)) 770 if (!assertPaused(errorString))
756 return; 771 return;
757 m_debuggerStepScheduled = false; 772 m_debuggerStepScheduled = false;
758 m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtrac eObjectGroup); 773 m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtrac eObjectGroup);
759 scriptDebugServer().continueProgram(); 774 scriptDebugServer().continueProgram();
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 { 1119 {
1105 ScriptDebugListener::SkipPauseRequest result; 1120 ScriptDebugListener::SkipPauseRequest result;
1106 if (m_javaScriptPauseScheduled) 1121 if (m_javaScriptPauseScheduled)
1107 result = ScriptDebugListener::NoSkip; // Don't skip explicit pause reque sts from front-end. 1122 result = ScriptDebugListener::NoSkip; // Don't skip explicit pause reque sts from front-end.
1108 else if (m_skipAllPauses) 1123 else if (m_skipAllPauses)
1109 result = ScriptDebugListener::Continue; 1124 result = ScriptDebugListener::Continue;
1110 else if (!hitBreakpoints.isEmpty()) 1125 else if (!hitBreakpoints.isEmpty())
1111 result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints even if set in frameworks. 1126 result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints even if set in frameworks.
1112 else if (!exception.isEmpty()) 1127 else if (!exception.isEmpty())
1113 result = shouldSkipExceptionPause(); 1128 result = shouldSkipExceptionPause();
1114 else if (m_debuggerStepScheduled) 1129 else if (m_debuggerStepScheduled || m_pausingOnNativeEvent)
1115 result = shouldSkipStepPause(); 1130 result = shouldSkipStepPause();
1116 else 1131 else
1117 result = ScriptDebugListener::NoSkip; 1132 result = ScriptDebugListener::NoSkip;
1118 1133
1119 if (result != ScriptDebugListener::NoSkip) 1134 if (result != ScriptDebugListener::NoSkip)
1120 return result; 1135 return result;
1121 1136
1122 ASSERT(scriptState && !m_pausedScriptState); 1137 ASSERT(scriptState && !m_pausedScriptState);
1123 m_pausedScriptState = scriptState; 1138 m_pausedScriptState = scriptState;
1124 m_currentCallStack = callFrames; 1139 m_currentCallStack = callFrames;
1125 1140
1126 m_skipStepInCount = numberOfStepsBeforeStepOut;
1127
1128 if (!exception.isEmpty()) { 1141 if (!exception.isEmpty()) {
1129 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptF or(scriptState); 1142 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptF or(scriptState);
1130 if (!injectedScript.isEmpty()) { 1143 if (!injectedScript.isEmpty()) {
1131 m_breakReason = InspectorFrontend::Debugger::Reason::Exception; 1144 m_breakReason = InspectorFrontend::Debugger::Reason::Exception;
1132 m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebug gerAgent::backtraceObjectGroup)->openAccessors(); 1145 m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebug gerAgent::backtraceObjectGroup)->openAccessors();
1133 // m_breakAuxData might be null after this. 1146 // m_breakAuxData might be null after this.
1134 } 1147 }
1135 } 1148 }
1136 1149
1137 RefPtr<Array<String> > hitBreakpointIds = Array<String>::create(); 1150 RefPtr<Array<String> > hitBreakpointIds = Array<String>::create();
1138 1151
1139 for (Vector<String>::const_iterator i = hitBreakpoints.begin(); i != hitBrea kpoints.end(); ++i) { 1152 for (Vector<String>::const_iterator i = hitBreakpoints.begin(); i != hitBrea kpoints.end(); ++i) {
1140 DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIter ator = m_serverBreakpoints.find(*i); 1153 DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIter ator = m_serverBreakpoints.find(*i);
1141 if (breakpointIterator != m_serverBreakpoints.end()) { 1154 if (breakpointIterator != m_serverBreakpoints.end()) {
1142 const String& localId = breakpointIterator->value.first; 1155 const String& localId = breakpointIterator->value.first;
1143 hitBreakpointIds->addItem(localId); 1156 hitBreakpointIds->addItem(localId);
1144 1157
1145 BreakpointSource source = breakpointIterator->value.second; 1158 BreakpointSource source = breakpointIterator->value.second;
1146 if (m_breakReason == InspectorFrontend::Debugger::Reason::Other && s ource == DebugCommandBreakpointSource) 1159 if (m_breakReason == InspectorFrontend::Debugger::Reason::Other && s ource == DebugCommandBreakpointSource)
1147 m_breakReason = InspectorFrontend::Debugger::Reason::DebugComman d; 1160 m_breakReason = InspectorFrontend::Debugger::Reason::DebugComman d;
1148 } 1161 }
1149 } 1162 }
1150 1163
1151 m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBr eakpointIds, currentAsyncStackTrace()); 1164 m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBr eakpointIds, currentAsyncStackTrace());
1152 m_javaScriptPauseScheduled = false; 1165 m_javaScriptPauseScheduled = false;
1153 m_debuggerStepScheduled = false; 1166 m_debuggerStepScheduled = false;
1167 m_pausingOnNativeEvent = false;
1168 m_skippedStepInCount = 0;
1154 1169
1155 if (!m_continueToLocationBreakpointId.isEmpty()) { 1170 if (!m_continueToLocationBreakpointId.isEmpty()) {
1156 scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId); 1171 scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
1157 m_continueToLocationBreakpointId = ""; 1172 m_continueToLocationBreakpointId = "";
1158 } 1173 }
1159 if (m_listener) 1174 if (m_listener)
1160 m_listener->didPause(); 1175 m_listener->didPause();
1161 return result; 1176 return result;
1162 } 1177 }
1163 1178
(...skipping 10 matching lines...) Expand all
1174 return scriptDebugServer().canBreakProgram(); 1189 return scriptDebugServer().canBreakProgram();
1175 } 1190 }
1176 1191
1177 void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E num breakReason, PassRefPtr<JSONObject> data) 1192 void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E num breakReason, PassRefPtr<JSONObject> data)
1178 { 1193 {
1179 if (m_skipAllPauses) 1194 if (m_skipAllPauses)
1180 return; 1195 return;
1181 m_breakReason = breakReason; 1196 m_breakReason = breakReason;
1182 m_breakAuxData = data; 1197 m_breakAuxData = data;
1183 m_debuggerStepScheduled = false; 1198 m_debuggerStepScheduled = false;
1199 m_pausingOnNativeEvent = false;
1184 scriptDebugServer().breakProgram(); 1200 scriptDebugServer().breakProgram();
1185 } 1201 }
1186 1202
1187 void InspectorDebuggerAgent::clear() 1203 void InspectorDebuggerAgent::clear()
1188 { 1204 {
1189 m_pausedScriptState = nullptr; 1205 m_pausedScriptState = nullptr;
1190 m_currentCallStack = ScriptValue(); 1206 m_currentCallStack = ScriptValue();
1191 m_scripts.clear(); 1207 m_scripts.clear();
1192 m_breakpointIdToDebugServerBreakpointIds.clear(); 1208 m_breakpointIdToDebugServerBreakpointIds.clear();
1193 m_asyncCallStackTracker.clear(); 1209 m_asyncCallStackTracker.clear();
1194 m_continueToLocationBreakpointId = String(); 1210 m_continueToLocationBreakpointId = String();
1195 clearBreakDetails(); 1211 clearBreakDetails();
1196 m_javaScriptPauseScheduled = false; 1212 m_javaScriptPauseScheduled = false;
1197 m_debuggerStepScheduled = false; 1213 m_debuggerStepScheduled = false;
1214 m_pausingOnNativeEvent = false;
1198 ErrorString error; 1215 ErrorString error;
1199 setOverlayMessage(&error, 0); 1216 setOverlayMessage(&error, 0);
1200 } 1217 }
1201 1218
1202 bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString) 1219 bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString)
1203 { 1220 {
1204 if (!m_pausedScriptState) { 1221 if (!m_pausedScriptState) {
1205 *errorString = "Can only perform operation while paused."; 1222 *errorString = "Can only perform operation while paused.";
1206 return false; 1223 return false;
1207 } 1224 }
(...skipping 22 matching lines...) Expand all
1230 { 1247 {
1231 m_scripts.clear(); 1248 m_scripts.clear();
1232 m_breakpointIdToDebugServerBreakpointIds.clear(); 1249 m_breakpointIdToDebugServerBreakpointIds.clear();
1233 m_asyncCallStackTracker.clear(); 1250 m_asyncCallStackTracker.clear();
1234 if (m_frontend) 1251 if (m_frontend)
1235 m_frontend->globalObjectCleared(); 1252 m_frontend->globalObjectCleared();
1236 } 1253 }
1237 1254
1238 } // namespace WebCore 1255 } // namespace WebCore
1239 1256
OLDNEW
« no previous file with comments | « Source/core/inspector/InspectorDebuggerAgent.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698