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

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

Issue 2471583003: [inspector] migrate Debugger to new style (Closed)
Patch Set: added missing readme.v8 Created 4 years, 1 month 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // Breakpoint properties. 47 // Breakpoint properties.
48 static const char url[] = "url"; 48 static const char url[] = "url";
49 static const char isRegex[] = "isRegex"; 49 static const char isRegex[] = "isRegex";
50 static const char lineNumber[] = "lineNumber"; 50 static const char lineNumber[] = "lineNumber";
51 static const char columnNumber[] = "columnNumber"; 51 static const char columnNumber[] = "columnNumber";
52 static const char condition[] = "condition"; 52 static const char condition[] = "condition";
53 static const char skipAllPauses[] = "skipAllPauses"; 53 static const char skipAllPauses[] = "skipAllPauses";
54 54
55 } // namespace DebuggerAgentState 55 } // namespace DebuggerAgentState
56 56
57 static const int maxSkipStepFrameCount = 128; 57 static const int kMaxSkipStepFrameCount = 128;
58 static const char backtraceObjectGroup[] = "backtrace"; 58 static const char kBacktraceObjectGroup[] = "backtrace";
59 static const char kDebuggerNotEnabled[] = "Debugger agent is not enabled";
60 static const char kDebuggerNotPaused[] =
61 "Can only perform operation while paused.";
59 62
60 static String16 breakpointIdSuffix( 63 static String16 breakpointIdSuffix(
61 V8DebuggerAgentImpl::BreakpointSource source) { 64 V8DebuggerAgentImpl::BreakpointSource source) {
62 switch (source) { 65 switch (source) {
63 case V8DebuggerAgentImpl::UserBreakpointSource: 66 case V8DebuggerAgentImpl::UserBreakpointSource:
64 break; 67 break;
65 case V8DebuggerAgentImpl::DebugCommandBreakpointSource: 68 case V8DebuggerAgentImpl::DebugCommandBreakpointSource:
66 return ":debug"; 69 return ":debug";
67 case V8DebuggerAgentImpl::MonitorCommandBreakpointSource: 70 case V8DebuggerAgentImpl::MonitorCommandBreakpointSource:
68 return ":monitor"; 71 return ":monitor";
69 } 72 }
70 return String16(); 73 return String16();
71 } 74 }
72 75
73 static String16 generateBreakpointId( 76 static String16 generateBreakpointId(
74 const String16& scriptId, int lineNumber, int columnNumber, 77 const String16& scriptId, int lineNumber, int columnNumber,
75 V8DebuggerAgentImpl::BreakpointSource source) { 78 V8DebuggerAgentImpl::BreakpointSource source) {
76 return scriptId + ":" + String16::fromInteger(lineNumber) + ":" + 79 return scriptId + ":" + String16::fromInteger(lineNumber) + ":" +
77 String16::fromInteger(columnNumber) + breakpointIdSuffix(source); 80 String16::fromInteger(columnNumber) + breakpointIdSuffix(source);
78 } 81 }
79 82
80 static bool positionComparator(const std::pair<int, int>& a, 83 static bool positionComparator(const std::pair<int, int>& a,
81 const std::pair<int, int>& b) { 84 const std::pair<int, int>& b) {
82 if (a.first != b.first) return a.first < b.first; 85 if (a.first != b.first) return a.first < b.first;
83 return a.second < b.second; 86 return a.second < b.second;
84 } 87 }
85 88
86 static bool hasInternalError(ErrorString* errorString, bool hasError) {
87 if (hasError) *errorString = "Internal error";
88 return hasError;
89 }
90
91 static std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation( 89 static std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation(
92 const String16& scriptId, int lineNumber, int columnNumber) { 90 const String16& scriptId, int lineNumber, int columnNumber) {
93 return protocol::Debugger::Location::create() 91 return protocol::Debugger::Location::create()
94 .setScriptId(scriptId) 92 .setScriptId(scriptId)
95 .setLineNumber(lineNumber) 93 .setLineNumber(lineNumber)
96 .setColumnNumber(columnNumber) 94 .setColumnNumber(columnNumber)
97 .build(); 95 .build();
98 } 96 }
99 97
100 V8DebuggerAgentImpl::V8DebuggerAgentImpl( 98 V8DebuggerAgentImpl::V8DebuggerAgentImpl(
(...skipping 14 matching lines...) Expand all
115 m_pausingOnNativeEvent(false), 113 m_pausingOnNativeEvent(false),
116 m_skippedStepFrameCount(0), 114 m_skippedStepFrameCount(0),
117 m_recursionLevelForStepOut(0), 115 m_recursionLevelForStepOut(0),
118 m_recursionLevelForStepFrame(0), 116 m_recursionLevelForStepFrame(0),
119 m_skipAllPauses(false) { 117 m_skipAllPauses(false) {
120 clearBreakDetails(); 118 clearBreakDetails();
121 } 119 }
122 120
123 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {} 121 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {}
124 122
125 bool V8DebuggerAgentImpl::checkEnabled(ErrorString* errorString) { 123 void V8DebuggerAgentImpl::enableImpl() {
126 if (enabled()) return true;
127 *errorString = "Debugger agent is not enabled";
128 return false;
129 }
130
131 void V8DebuggerAgentImpl::enable() {
132 // m_inspector->addListener may result in reporting all parsed scripts to 124 // m_inspector->addListener may result in reporting all parsed scripts to
133 // the agent so it should already be in enabled state by then. 125 // the agent so it should already be in enabled state by then.
134 m_enabled = true; 126 m_enabled = true;
135 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); 127 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
136 m_debugger->enable(); 128 m_debugger->enable();
137 129
138 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts; 130 std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts;
139 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); 131 m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts);
140 for (size_t i = 0; i < compiledScripts.size(); i++) 132 for (size_t i = 0; i < compiledScripts.size(); i++)
141 didParseSource(std::move(compiledScripts[i]), true); 133 didParseSource(std::move(compiledScripts[i]), true);
142 134
143 // FIXME(WK44513): breakpoints activated flag should be synchronized between 135 // FIXME(WK44513): breakpoints activated flag should be synchronized between
144 // all front-ends 136 // all front-ends
145 m_debugger->setBreakpointsActivated(true); 137 m_debugger->setBreakpointsActivated(true);
146 } 138 }
147 139
148 bool V8DebuggerAgentImpl::enabled() { return m_enabled; } 140 bool V8DebuggerAgentImpl::enabled() { return m_enabled; }
149 141
150 void V8DebuggerAgentImpl::enable(ErrorString* errorString) { 142 Response V8DebuggerAgentImpl::enable() {
151 if (enabled()) return; 143 if (enabled()) return Response::OK();
152 144
153 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) { 145 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
154 *errorString = "Script execution is prohibited"; 146 return Response::Error("Script execution is prohibited");
155 return;
156 }
157 147
158 enable(); 148 enableImpl();
149 return Response::OK();
159 } 150 }
160 151
161 void V8DebuggerAgentImpl::disable(ErrorString*) { 152 Response V8DebuggerAgentImpl::disable() {
162 if (!enabled()) return; 153 if (!enabled()) return Response::OK();
163 154
164 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, 155 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints,
165 protocol::DictionaryValue::create()); 156 protocol::DictionaryValue::create());
166 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, 157 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
167 v8::DebugInterface::NoBreakOnException); 158 v8::DebugInterface::NoBreakOnException);
168 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); 159 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0);
169 160
170 if (!m_pausedContext.IsEmpty()) m_debugger->continueProgram(); 161 if (!m_pausedContext.IsEmpty()) m_debugger->continueProgram();
171 m_debugger->disable(); 162 m_debugger->disable();
172 m_pausedContext.Reset(); 163 m_pausedContext.Reset();
(...skipping 10 matching lines...) Expand all
183 m_javaScriptPauseScheduled = false; 174 m_javaScriptPauseScheduled = false;
184 m_steppingFromFramework = false; 175 m_steppingFromFramework = false;
185 m_pausingOnNativeEvent = false; 176 m_pausingOnNativeEvent = false;
186 m_skippedStepFrameCount = 0; 177 m_skippedStepFrameCount = 0;
187 m_recursionLevelForStepFrame = 0; 178 m_recursionLevelForStepFrame = 0;
188 m_skipAllPauses = false; 179 m_skipAllPauses = false;
189 m_blackboxPattern = nullptr; 180 m_blackboxPattern = nullptr;
190 m_state->remove(DebuggerAgentState::blackboxPattern); 181 m_state->remove(DebuggerAgentState::blackboxPattern);
191 m_enabled = false; 182 m_enabled = false;
192 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false); 183 m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
184 return Response::OK();
193 } 185 }
194 186
195 void V8DebuggerAgentImpl::restore() { 187 void V8DebuggerAgentImpl::restore() {
196 DCHECK(!m_enabled); 188 DCHECK(!m_enabled);
197 if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false)) 189 if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false))
198 return; 190 return;
199 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) 191 if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
200 return; 192 return;
201 193
202 enable(); 194 enableImpl();
203 195
204 int pauseState = v8::DebugInterface::NoBreakOnException; 196 int pauseState = v8::DebugInterface::NoBreakOnException;
205 m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState); 197 m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
206 setPauseOnExceptionsImpl(pauseState); 198 setPauseOnExceptionsImpl(pauseState);
207 199
208 m_skipAllPauses = 200 m_skipAllPauses =
209 m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false); 201 m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
210 202
211 int asyncCallStackDepth = 0; 203 int asyncCallStackDepth = 0;
212 m_state->getInteger(DebuggerAgentState::asyncCallStackDepth, 204 m_state->getInteger(DebuggerAgentState::asyncCallStackDepth,
213 &asyncCallStackDepth); 205 &asyncCallStackDepth);
214 m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth); 206 m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth);
215 207
216 String16 blackboxPattern; 208 String16 blackboxPattern;
217 if (m_state->getString(DebuggerAgentState::blackboxPattern, 209 if (m_state->getString(DebuggerAgentState::blackboxPattern,
218 &blackboxPattern)) { 210 &blackboxPattern)) {
219 ErrorString error; 211 Response response = setBlackboxPattern(blackboxPattern);
220 if (!setBlackboxPattern(&error, blackboxPattern)) UNREACHABLE(); 212 CHECK(response.isSuccess());
dgozman 2016/11/04 01:49:04 Just ignore the result?
kozy 2016/11/04 14:33:57 Done.
221 } 213 }
222 } 214 }
223 215
224 void V8DebuggerAgentImpl::setBreakpointsActive(ErrorString* errorString, 216 Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) {
225 bool active) { 217 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
226 if (!checkEnabled(errorString)) return;
227 m_debugger->setBreakpointsActivated(active); 218 m_debugger->setBreakpointsActivated(active);
219 return Response::OK();
228 } 220 }
229 221
230 void V8DebuggerAgentImpl::setSkipAllPauses(ErrorString*, bool skip) { 222 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) {
231 m_skipAllPauses = skip; 223 m_skipAllPauses = skip;
232 m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses); 224 m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
225 return Response::OK();
233 } 226 }
234 227
235 static std::unique_ptr<protocol::DictionaryValue> 228 static std::unique_ptr<protocol::DictionaryValue>
236 buildObjectForBreakpointCookie(const String16& url, int lineNumber, 229 buildObjectForBreakpointCookie(const String16& url, int lineNumber,
237 int columnNumber, const String16& condition, 230 int columnNumber, const String16& condition,
238 bool isRegex) { 231 bool isRegex) {
239 std::unique_ptr<protocol::DictionaryValue> breakpointObject = 232 std::unique_ptr<protocol::DictionaryValue> breakpointObject =
240 protocol::DictionaryValue::create(); 233 protocol::DictionaryValue::create();
241 breakpointObject->setString(DebuggerAgentState::url, url); 234 breakpointObject->setString(DebuggerAgentState::url, url);
242 breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); 235 breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber);
243 breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); 236 breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber);
244 breakpointObject->setString(DebuggerAgentState::condition, condition); 237 breakpointObject->setString(DebuggerAgentState::condition, condition);
245 breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex); 238 breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex);
246 return breakpointObject; 239 return breakpointObject;
247 } 240 }
248 241
249 static bool matches(V8InspectorImpl* inspector, const String16& url, 242 static bool matches(V8InspectorImpl* inspector, const String16& url,
250 const String16& pattern, bool isRegex) { 243 const String16& pattern, bool isRegex) {
251 if (isRegex) { 244 if (isRegex) {
252 V8Regex regex(inspector, pattern, true); 245 V8Regex regex(inspector, pattern, true);
253 return regex.match(url) != -1; 246 return regex.match(url) != -1;
254 } 247 }
255 return url == pattern; 248 return url == pattern;
256 } 249 }
257 250
258 void V8DebuggerAgentImpl::setBreakpointByUrl( 251 Response V8DebuggerAgentImpl::setBreakpointByUrl(
259 ErrorString* errorString, int lineNumber, 252 int lineNumber, Maybe<String16> optionalURL,
260 const Maybe<String16>& optionalURL, const Maybe<String16>& optionalURLRegex, 253 Maybe<String16> optionalURLRegex, Maybe<int> optionalColumnNumber,
261 const Maybe<int>& optionalColumnNumber, 254 Maybe<String16> optionalCondition, String16* outBreakpointId,
262 const Maybe<String16>& optionalCondition, String16* outBreakpointId,
263 std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { 255 std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) {
264 *locations = Array<protocol::Debugger::Location>::create(); 256 *locations = Array<protocol::Debugger::Location>::create();
265 if (optionalURL.isJust() == optionalURLRegex.isJust()) { 257 if (optionalURL.isJust() == optionalURLRegex.isJust())
266 *errorString = "Either url or urlRegex must be specified."; 258 return Response::Error("Either url or urlRegex must be specified.");
267 return;
268 }
269 259
270 String16 url = optionalURL.isJust() ? optionalURL.fromJust() 260 String16 url = optionalURL.isJust() ? optionalURL.fromJust()
271 : optionalURLRegex.fromJust(); 261 : optionalURLRegex.fromJust();
272 int columnNumber = 0; 262 int columnNumber = 0;
273 if (optionalColumnNumber.isJust()) { 263 if (optionalColumnNumber.isJust()) {
274 columnNumber = optionalColumnNumber.fromJust(); 264 columnNumber = optionalColumnNumber.fromJust();
275 if (columnNumber < 0) { 265 if (columnNumber < 0) return Response::Error("Incorrect column number");
276 *errorString = "Incorrect column number";
277 return;
278 }
279 } 266 }
280 String16 condition = optionalCondition.fromMaybe(""); 267 String16 condition = optionalCondition.fromMaybe("");
281 bool isRegex = optionalURLRegex.isJust(); 268 bool isRegex = optionalURLRegex.isJust();
282 269
283 String16 breakpointId = (isRegex ? "/" + url + "/" : url) + ":" + 270 String16 breakpointId = (isRegex ? "/" + url + "/" : url) + ":" +
284 String16::fromInteger(lineNumber) + ":" + 271 String16::fromInteger(lineNumber) + ":" +
285 String16::fromInteger(columnNumber); 272 String16::fromInteger(columnNumber);
286 protocol::DictionaryValue* breakpointsCookie = 273 protocol::DictionaryValue* breakpointsCookie =
287 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); 274 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
288 if (!breakpointsCookie) { 275 if (!breakpointsCookie) {
289 std::unique_ptr<protocol::DictionaryValue> newValue = 276 std::unique_ptr<protocol::DictionaryValue> newValue =
290 protocol::DictionaryValue::create(); 277 protocol::DictionaryValue::create();
291 breakpointsCookie = newValue.get(); 278 breakpointsCookie = newValue.get();
292 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, 279 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints,
293 std::move(newValue)); 280 std::move(newValue));
294 } 281 }
295 if (breakpointsCookie->get(breakpointId)) { 282 if (breakpointsCookie->get(breakpointId))
296 *errorString = "Breakpoint at specified location already exists."; 283 return Response::Error("Breakpoint at specified location already exists.");
297 return;
298 }
299 284
300 breakpointsCookie->setObject( 285 breakpointsCookie->setObject(
301 breakpointId, buildObjectForBreakpointCookie( 286 breakpointId, buildObjectForBreakpointCookie(
302 url, lineNumber, columnNumber, condition, isRegex)); 287 url, lineNumber, columnNumber, condition, isRegex));
303 288
304 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); 289 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
305 for (const auto& script : m_scripts) { 290 for (const auto& script : m_scripts) {
306 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) 291 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex))
307 continue; 292 continue;
308 std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( 293 std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint(
309 breakpointId, script.first, breakpoint, UserBreakpointSource); 294 breakpointId, script.first, breakpoint, UserBreakpointSource);
310 if (location) (*locations)->addItem(std::move(location)); 295 if (location) (*locations)->addItem(std::move(location));
311 } 296 }
312 297
313 *outBreakpointId = breakpointId; 298 *outBreakpointId = breakpointId;
299 return Response::OK();
314 } 300 }
315 301
316 static bool parseLocation( 302 static void parseLocation(
dgozman 2016/11/04 01:49:04 Just remove this method.
kozy 2016/11/04 14:33:57 Done.
317 ErrorString* errorString,
318 std::unique_ptr<protocol::Debugger::Location> location, String16* scriptId, 303 std::unique_ptr<protocol::Debugger::Location> location, String16* scriptId,
319 int* lineNumber, int* columnNumber) { 304 int* lineNumber, int* columnNumber) {
320 *scriptId = location->getScriptId(); 305 *scriptId = location->getScriptId();
321 *lineNumber = location->getLineNumber(); 306 *lineNumber = location->getLineNumber();
322 *columnNumber = location->getColumnNumber(0); 307 *columnNumber = location->getColumnNumber(0);
323 return true;
324 } 308 }
325 309
326 void V8DebuggerAgentImpl::setBreakpoint( 310 Response V8DebuggerAgentImpl::setBreakpoint(
327 ErrorString* errorString,
328 std::unique_ptr<protocol::Debugger::Location> location, 311 std::unique_ptr<protocol::Debugger::Location> location,
329 const Maybe<String16>& optionalCondition, String16* outBreakpointId, 312 Maybe<String16> optionalCondition, String16* outBreakpointId,
330 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { 313 std::unique_ptr<protocol::Debugger::Location>* actualLocation) {
331 String16 scriptId; 314 String16 scriptId;
332 int lineNumber; 315 int lineNumber;
333 int columnNumber; 316 int columnNumber;
334 317
335 if (!parseLocation(errorString, std::move(location), &scriptId, &lineNumber, 318 parseLocation(std::move(location), &scriptId, &lineNumber, &columnNumber);
336 &columnNumber))
337 return;
338 319
339 String16 condition = optionalCondition.fromMaybe(""); 320 String16 condition = optionalCondition.fromMaybe("");
340 321
341 String16 breakpointId = generateBreakpointId( 322 String16 breakpointId = generateBreakpointId(
342 scriptId, lineNumber, columnNumber, UserBreakpointSource); 323 scriptId, lineNumber, columnNumber, UserBreakpointSource);
343 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != 324 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
344 m_breakpointIdToDebuggerBreakpointIds.end()) { 325 m_breakpointIdToDebuggerBreakpointIds.end()) {
345 *errorString = "Breakpoint at specified location already exists."; 326 return Response::Error("Breakpoint at specified location already exists.");
346 return;
347 } 327 }
348 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); 328 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
349 *actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, 329 *actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint,
350 UserBreakpointSource); 330 UserBreakpointSource);
351 if (*actualLocation) 331 if (!*actualLocation) return Response::Error("Could not resolve breakpoint");
352 *outBreakpointId = breakpointId; 332 *outBreakpointId = breakpointId;
353 else 333 return Response::OK();
354 *errorString = "Could not resolve breakpoint";
355 } 334 }
356 335
357 void V8DebuggerAgentImpl::removeBreakpoint(ErrorString* errorString, 336 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
358 const String16& breakpointId) { 337 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
359 if (!checkEnabled(errorString)) return;
360 protocol::DictionaryValue* breakpointsCookie = 338 protocol::DictionaryValue* breakpointsCookie =
361 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); 339 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
362 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); 340 if (breakpointsCookie) breakpointsCookie->remove(breakpointId);
363 removeBreakpoint(breakpointId); 341 removeBreakpointImpl(breakpointId);
342 return Response::OK();
364 } 343 }
365 344
366 void V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { 345 void V8DebuggerAgentImpl::removeBreakpointImpl(const String16& breakpointId) {
367 DCHECK(enabled()); 346 DCHECK(enabled());
368 BreakpointIdToDebuggerBreakpointIdsMap::iterator 347 BreakpointIdToDebuggerBreakpointIdsMap::iterator
369 debuggerBreakpointIdsIterator = 348 debuggerBreakpointIdsIterator =
370 m_breakpointIdToDebuggerBreakpointIds.find(breakpointId); 349 m_breakpointIdToDebuggerBreakpointIds.find(breakpointId);
371 if (debuggerBreakpointIdsIterator == 350 if (debuggerBreakpointIdsIterator ==
372 m_breakpointIdToDebuggerBreakpointIds.end()) 351 m_breakpointIdToDebuggerBreakpointIds.end())
373 return; 352 return;
374 const std::vector<String16>& ids = debuggerBreakpointIdsIterator->second; 353 const std::vector<String16>& ids = debuggerBreakpointIdsIterator->second;
375 for (size_t i = 0; i < ids.size(); ++i) { 354 for (size_t i = 0; i < ids.size(); ++i) {
376 const String16& debuggerBreakpointId = ids[i]; 355 const String16& debuggerBreakpointId = ids[i];
377 356
378 m_debugger->removeBreakpoint(debuggerBreakpointId); 357 m_debugger->removeBreakpoint(debuggerBreakpointId);
379 m_serverBreakpoints.erase(debuggerBreakpointId); 358 m_serverBreakpoints.erase(debuggerBreakpointId);
380 } 359 }
381 m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId); 360 m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId);
382 } 361 }
383 362
384 void V8DebuggerAgentImpl::continueToLocation( 363 Response V8DebuggerAgentImpl::continueToLocation(
385 ErrorString* errorString,
386 std::unique_ptr<protocol::Debugger::Location> location) { 364 std::unique_ptr<protocol::Debugger::Location> location) {
387 if (!checkEnabled(errorString)) return; 365 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
388 if (!m_continueToLocationBreakpointId.isEmpty()) { 366 if (!m_continueToLocationBreakpointId.isEmpty()) {
389 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); 367 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
390 m_continueToLocationBreakpointId = ""; 368 m_continueToLocationBreakpointId = "";
391 } 369 }
392 370
393 String16 scriptId; 371 String16 scriptId;
394 int lineNumber; 372 int lineNumber;
395 int columnNumber; 373 int columnNumber;
396 374
397 if (!parseLocation(errorString, std::move(location), &scriptId, &lineNumber, 375 parseLocation(std::move(location), &scriptId, &lineNumber, &columnNumber);
398 &columnNumber))
399 return;
400 376
401 ScriptBreakpoint breakpoint(lineNumber, columnNumber, ""); 377 ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
402 m_continueToLocationBreakpointId = m_debugger->setBreakpoint( 378 m_continueToLocationBreakpointId = m_debugger->setBreakpoint(
403 scriptId, breakpoint, &lineNumber, &columnNumber); 379 scriptId, breakpoint, &lineNumber, &columnNumber);
404 resume(errorString); 380 return resume();
405 } 381 }
406 382
407 bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { 383 bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() {
408 DCHECK(enabled()); 384 DCHECK(enabled());
409 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(); 385 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames();
410 for (size_t index = 0; index < callFrames.size(); ++index) { 386 for (size_t index = 0; index < callFrames.size(); ++index) {
411 if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) 387 if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get()))
412 return false; 388 return false;
413 } 389 }
414 return true; 390 return true;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 if (m_steppingFromFramework) return RequestNoSkip; 441 if (m_steppingFromFramework) return RequestNoSkip;
466 442
467 if (m_skipNextDebuggerStepOut) { 443 if (m_skipNextDebuggerStepOut) {
468 m_skipNextDebuggerStepOut = false; 444 m_skipNextDebuggerStepOut = false;
469 if (m_scheduledDebuggerStep == StepOut) return RequestStepOut; 445 if (m_scheduledDebuggerStep == StepOut) return RequestStepOut;
470 } 446 }
471 447
472 if (!isCallFrameWithUnknownScriptOrBlackboxed(topCallFrame)) 448 if (!isCallFrameWithUnknownScriptOrBlackboxed(topCallFrame))
473 return RequestNoSkip; 449 return RequestNoSkip;
474 450
475 if (m_skippedStepFrameCount >= maxSkipStepFrameCount) return RequestStepOut; 451 if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut;
476 452
477 if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1; 453 if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1;
478 454
479 ++m_skippedStepFrameCount; 455 ++m_skippedStepFrameCount;
480 return RequestStepFrame; 456 return RequestStepFrame;
481 } 457 }
482 458
483 std::unique_ptr<protocol::Debugger::Location> 459 std::unique_ptr<protocol::Debugger::Location>
484 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, 460 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId,
485 const String16& scriptId, 461 const String16& scriptId,
(...skipping 17 matching lines...) Expand all
503 479
504 m_serverBreakpoints[debuggerBreakpointId] = 480 m_serverBreakpoints[debuggerBreakpointId] =
505 std::make_pair(breakpointId, source); 481 std::make_pair(breakpointId, source);
506 CHECK(!breakpointId.isEmpty()); 482 CHECK(!breakpointId.isEmpty());
507 483
508 m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back( 484 m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
509 debuggerBreakpointId); 485 debuggerBreakpointId);
510 return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber); 486 return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber);
511 } 487 }
512 488
513 void V8DebuggerAgentImpl::searchInContent( 489 Response V8DebuggerAgentImpl::searchInContent(
514 ErrorString* error, const String16& scriptId, const String16& query, 490 const String16& scriptId, const String16& query,
515 const Maybe<bool>& optionalCaseSensitive, 491 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
516 const Maybe<bool>& optionalIsRegex,
517 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { 492 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) {
518 v8::HandleScope handles(m_isolate); 493 v8::HandleScope handles(m_isolate);
519 ScriptsMap::iterator it = m_scripts.find(scriptId); 494 ScriptsMap::iterator it = m_scripts.find(scriptId);
520 if (it == m_scripts.end()) { 495 if (it == m_scripts.end())
521 *error = String16("No script for id: " + scriptId); 496 return Response::Error("No script for id: " + scriptId);
522 return;
523 }
524 497
525 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = 498 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches =
526 searchInTextByLinesImpl(m_session, 499 searchInTextByLinesImpl(m_session,
527 toProtocolString(it->second->source(m_isolate)), 500 toProtocolString(it->second->source(m_isolate)),
528 query, optionalCaseSensitive.fromMaybe(false), 501 query, optionalCaseSensitive.fromMaybe(false),
529 optionalIsRegex.fromMaybe(false)); 502 optionalIsRegex.fromMaybe(false));
530 *results = protocol::Array<protocol::Debugger::SearchMatch>::create(); 503 *results = protocol::Array<protocol::Debugger::SearchMatch>::create();
531 for (size_t i = 0; i < matches.size(); ++i) 504 for (size_t i = 0; i < matches.size(); ++i)
532 (*results)->addItem(std::move(matches[i])); 505 (*results)->addItem(std::move(matches[i]));
506 return Response::OK();
533 } 507 }
534 508
535 void V8DebuggerAgentImpl::setScriptSource( 509 Response V8DebuggerAgentImpl::setScriptSource(
536 ErrorString* errorString, const String16& scriptId, 510 const String16& scriptId, const String16& newContent, Maybe<bool> dryRun,
537 const String16& newContent, const Maybe<bool>& dryRun,
538 Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames, 511 Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames,
539 Maybe<bool>* stackChanged, Maybe<StackTrace>* asyncStackTrace, 512 Maybe<bool>* stackChanged, Maybe<StackTrace>* asyncStackTrace,
540 Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) { 513 Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) {
541 if (!checkEnabled(errorString)) return; 514 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
542 515
543 v8::HandleScope handles(m_isolate); 516 v8::HandleScope handles(m_isolate);
544 v8::Local<v8::String> newSource = toV8String(m_isolate, newContent); 517 v8::Local<v8::String> newSource = toV8String(m_isolate, newContent);
545 if (!m_debugger->setScriptSource(scriptId, newSource, dryRun.fromMaybe(false), 518 bool compileError = false;
546 errorString, optOutCompileError, 519 Response response = m_debugger->setScriptSource(
547 &m_pausedCallFrames, stackChanged)) 520 scriptId, newSource, dryRun.fromMaybe(false), optOutCompileError,
548 return; 521 &m_pausedCallFrames, stackChanged, &compileError);
522 if (!response.isSuccess() || compileError) return response;
dgozman 2016/11/04 01:49:04 If there was a compile error, don't you want to re
kozy 2016/11/04 14:33:57 No, I'll return exception details in this case and
549 523
550 ScriptsMap::iterator it = m_scripts.find(scriptId); 524 ScriptsMap::iterator it = m_scripts.find(scriptId);
551 if (it != m_scripts.end()) it->second->setSource(m_isolate, newSource); 525 if (it != m_scripts.end()) it->second->setSource(m_isolate, newSource);
552 526
553 std::unique_ptr<Array<CallFrame>> callFrames = currentCallFrames(errorString); 527 std::unique_ptr<Array<CallFrame>> callFrames;
554 if (!callFrames) return; 528 response = currentCallFrames(&callFrames);
529 if (!response.isSuccess()) return response;
555 *newCallFrames = std::move(callFrames); 530 *newCallFrames = std::move(callFrames);
556 *asyncStackTrace = currentAsyncStackTrace(); 531 *asyncStackTrace = currentAsyncStackTrace();
532 return Response::OK();
557 } 533 }
558 534
559 void V8DebuggerAgentImpl::restartFrame( 535 Response V8DebuggerAgentImpl::restartFrame(
560 ErrorString* errorString, const String16& callFrameId, 536 const String16& callFrameId,
561 std::unique_ptr<Array<CallFrame>>* newCallFrames, 537 std::unique_ptr<Array<CallFrame>>* newCallFrames,
562 Maybe<StackTrace>* asyncStackTrace) { 538 Maybe<StackTrace>* asyncStackTrace) {
563 if (!assertPaused(errorString)) return; 539 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
564 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 540 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
565 callFrameId); 541 callFrameId);
566 Response response = scope.initialize(); 542 Response response = scope.initialize();
567 if (!response.isSuccess()) { 543 if (!response.isSuccess()) return response;
568 *errorString = response.errorMessage(); 544 if (scope.frameOrdinal() >= m_pausedCallFrames.size())
569 return; 545 return Response::Error("Could not find call frame with given id");
570 }
571 if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
572 *errorString = "Could not find call frame with given id";
573 return;
574 }
575 546
576 v8::Local<v8::Value> resultValue; 547 v8::Local<v8::Value> resultValue;
577 v8::Local<v8::Boolean> result; 548 v8::Local<v8::Boolean> result;
578 if (!m_pausedCallFrames[scope.frameOrdinal()]->restart().ToLocal( 549 if (!m_pausedCallFrames[scope.frameOrdinal()]->restart().ToLocal(
579 &resultValue) || 550 &resultValue) ||
580 scope.tryCatch().HasCaught() || 551 scope.tryCatch().HasCaught() ||
581 !resultValue->ToBoolean(scope.context()).ToLocal(&result) || 552 !resultValue->ToBoolean(scope.context()).ToLocal(&result) ||
582 !result->Value()) { 553 !result->Value()) {
583 *errorString = "Internal error"; 554 return Response::Error("Internal error");
dgozman 2016/11/04 01:49:04 InternalError()
kozy 2016/11/04 14:33:57 Done.
584 return;
585 } 555 }
586 JavaScriptCallFrames frames = m_debugger->currentCallFrames(); 556 JavaScriptCallFrames frames = m_debugger->currentCallFrames();
587 m_pausedCallFrames.swap(frames); 557 m_pausedCallFrames.swap(frames);
588 558
589 *newCallFrames = currentCallFrames(errorString); 559 response = currentCallFrames(newCallFrames);
590 if (!*newCallFrames) return; 560 if (!response.isSuccess()) return response;
591 *asyncStackTrace = currentAsyncStackTrace(); 561 *asyncStackTrace = currentAsyncStackTrace();
562 return Response::OK();
592 } 563 }
593 564
594 void V8DebuggerAgentImpl::getScriptSource(ErrorString* error, 565 Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId,
595 const String16& scriptId, 566 String16* scriptSource) {
596 String16* scriptSource) { 567 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
597 if (!checkEnabled(error)) return;
598 ScriptsMap::iterator it = m_scripts.find(scriptId); 568 ScriptsMap::iterator it = m_scripts.find(scriptId);
599 if (it == m_scripts.end()) { 569 if (it == m_scripts.end())
600 *error = "No script for id: " + scriptId; 570 return Response::Error("No script for id: " + scriptId);
601 return;
602 }
603 v8::HandleScope handles(m_isolate); 571 v8::HandleScope handles(m_isolate);
604 *scriptSource = toProtocolString(it->second->source(m_isolate)); 572 *scriptSource = toProtocolString(it->second->source(m_isolate));
573 return Response::OK();
605 } 574 }
606 575
607 void V8DebuggerAgentImpl::schedulePauseOnNextStatement( 576 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
608 const String16& breakReason, 577 const String16& breakReason,
609 std::unique_ptr<protocol::DictionaryValue> data) { 578 std::unique_ptr<protocol::DictionaryValue> data) {
610 if (!enabled() || m_scheduledDebuggerStep == StepInto || 579 if (!enabled() || m_scheduledDebuggerStep == StepInto ||
611 m_javaScriptPauseScheduled || m_debugger->isPaused() || 580 m_javaScriptPauseScheduled || m_debugger->isPaused() ||
612 !m_debugger->breakpointsActivated()) 581 !m_debugger->breakpointsActivated())
613 return; 582 return;
614 m_breakReason = breakReason; 583 m_breakReason = breakReason;
(...skipping 15 matching lines...) Expand all
630 m_debugger->setPauseOnNextStatement(true); 599 m_debugger->setPauseOnNextStatement(true);
631 } 600 }
632 601
633 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { 602 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
634 if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return; 603 if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return;
635 clearBreakDetails(); 604 clearBreakDetails();
636 m_pausingOnNativeEvent = false; 605 m_pausingOnNativeEvent = false;
637 m_debugger->setPauseOnNextStatement(false); 606 m_debugger->setPauseOnNextStatement(false);
638 } 607 }
639 608
640 void V8DebuggerAgentImpl::pause(ErrorString* errorString) { 609 Response V8DebuggerAgentImpl::pause() {
641 if (!checkEnabled(errorString)) return; 610 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
642 if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return; 611 if (m_javaScriptPauseScheduled || m_debugger->isPaused())
612 return Response::OK();
643 clearBreakDetails(); 613 clearBreakDetails();
644 m_javaScriptPauseScheduled = true; 614 m_javaScriptPauseScheduled = true;
645 m_scheduledDebuggerStep = NoStep; 615 m_scheduledDebuggerStep = NoStep;
646 m_skippedStepFrameCount = 0; 616 m_skippedStepFrameCount = 0;
647 m_steppingFromFramework = false; 617 m_steppingFromFramework = false;
648 m_debugger->setPauseOnNextStatement(true); 618 m_debugger->setPauseOnNextStatement(true);
619 return Response::OK();
649 } 620 }
650 621
651 void V8DebuggerAgentImpl::resume(ErrorString* errorString) { 622 Response V8DebuggerAgentImpl::resume() {
652 if (!assertPaused(errorString)) return; 623 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
653 m_scheduledDebuggerStep = NoStep; 624 m_scheduledDebuggerStep = NoStep;
654 m_steppingFromFramework = false; 625 m_steppingFromFramework = false;
655 m_session->releaseObjectGroup(backtraceObjectGroup); 626 m_session->releaseObjectGroup(kBacktraceObjectGroup);
656 m_debugger->continueProgram(); 627 m_debugger->continueProgram();
628 return Response::OK();
657 } 629 }
658 630
659 void V8DebuggerAgentImpl::stepOver(ErrorString* errorString) { 631 Response V8DebuggerAgentImpl::stepOver() {
660 if (!assertPaused(errorString)) return; 632 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
661 // StepOver at function return point should fallback to StepInto. 633 // StepOver at function return point should fallback to StepInto.
662 JavaScriptCallFrame* frame = 634 JavaScriptCallFrame* frame =
663 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr; 635 !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr;
664 if (frame && frame->isAtReturn()) { 636 if (frame && frame->isAtReturn()) return stepInto();
665 stepInto(errorString);
666 return;
667 }
668 m_scheduledDebuggerStep = StepOver; 637 m_scheduledDebuggerStep = StepOver;
669 m_steppingFromFramework = isTopPausedCallFrameBlackboxed(); 638 m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
670 m_session->releaseObjectGroup(backtraceObjectGroup); 639 m_session->releaseObjectGroup(kBacktraceObjectGroup);
671 m_debugger->stepOverStatement(); 640 m_debugger->stepOverStatement();
641 return Response::OK();
672 } 642 }
673 643
674 void V8DebuggerAgentImpl::stepInto(ErrorString* errorString) { 644 Response V8DebuggerAgentImpl::stepInto() {
675 if (!assertPaused(errorString)) return; 645 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
676 m_scheduledDebuggerStep = StepInto; 646 m_scheduledDebuggerStep = StepInto;
677 m_steppingFromFramework = isTopPausedCallFrameBlackboxed(); 647 m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
678 m_session->releaseObjectGroup(backtraceObjectGroup); 648 m_session->releaseObjectGroup(kBacktraceObjectGroup);
679 m_debugger->stepIntoStatement(); 649 m_debugger->stepIntoStatement();
650 return Response::OK();
680 } 651 }
681 652
682 void V8DebuggerAgentImpl::stepOut(ErrorString* errorString) { 653 Response V8DebuggerAgentImpl::stepOut() {
683 if (!assertPaused(errorString)) return; 654 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
684 m_scheduledDebuggerStep = StepOut; 655 m_scheduledDebuggerStep = StepOut;
685 m_skipNextDebuggerStepOut = false; 656 m_skipNextDebuggerStepOut = false;
686 m_recursionLevelForStepOut = 1; 657 m_recursionLevelForStepOut = 1;
687 m_steppingFromFramework = isTopPausedCallFrameBlackboxed(); 658 m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
688 m_session->releaseObjectGroup(backtraceObjectGroup); 659 m_session->releaseObjectGroup(kBacktraceObjectGroup);
689 m_debugger->stepOutOfFunction(); 660 m_debugger->stepOutOfFunction();
661 return Response::OK();
690 } 662 }
691 663
692 void V8DebuggerAgentImpl::setPauseOnExceptions( 664 Response V8DebuggerAgentImpl::setPauseOnExceptions(
693 ErrorString* errorString, const String16& stringPauseState) { 665 const String16& stringPauseState) {
694 if (!checkEnabled(errorString)) return; 666 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
695 v8::DebugInterface::ExceptionBreakState pauseState; 667 v8::DebugInterface::ExceptionBreakState pauseState;
696 if (stringPauseState == "none") { 668 if (stringPauseState == "none") {
697 pauseState = v8::DebugInterface::NoBreakOnException; 669 pauseState = v8::DebugInterface::NoBreakOnException;
698 } else if (stringPauseState == "all") { 670 } else if (stringPauseState == "all") {
699 pauseState = v8::DebugInterface::BreakOnAnyException; 671 pauseState = v8::DebugInterface::BreakOnAnyException;
700 } else if (stringPauseState == "uncaught") { 672 } else if (stringPauseState == "uncaught") {
701 pauseState = v8::DebugInterface::BreakOnUncaughtException; 673 pauseState = v8::DebugInterface::BreakOnUncaughtException;
702 } else { 674 } else {
703 *errorString = "Unknown pause on exceptions mode: " + stringPauseState; 675 return Response::Error("Unknown pause on exceptions mode: " +
704 return; 676 stringPauseState);
705 } 677 }
706 setPauseOnExceptionsImpl(pauseState); 678 setPauseOnExceptionsImpl(pauseState);
679 return Response::OK();
707 } 680 }
708 681
709 void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) { 682 void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) {
710 m_debugger->setPauseOnExceptionsState( 683 m_debugger->setPauseOnExceptionsState(
711 static_cast<v8::DebugInterface::ExceptionBreakState>(pauseState)); 684 static_cast<v8::DebugInterface::ExceptionBreakState>(pauseState));
712 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState); 685 m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState);
713 } 686 }
714 687
715 void V8DebuggerAgentImpl::evaluateOnCallFrame( 688 Response V8DebuggerAgentImpl::evaluateOnCallFrame(
716 ErrorString* errorString, const String16& callFrameId, 689 const String16& callFrameId, const String16& expression,
717 const String16& expression, const Maybe<String16>& objectGroup, 690 Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
718 const Maybe<bool>& includeCommandLineAPI, const Maybe<bool>& silent, 691 Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
719 const Maybe<bool>& returnByValue, const Maybe<bool>& generatePreview,
720 std::unique_ptr<RemoteObject>* result, 692 std::unique_ptr<RemoteObject>* result,
721 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { 693 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
722 if (!assertPaused(errorString)) return; 694 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
723 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 695 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
724 callFrameId); 696 callFrameId);
725 Response response = scope.initialize(); 697 Response response = scope.initialize();
726 if (!response.isSuccess()) { 698 if (!response.isSuccess()) return response;
727 *errorString = response.errorMessage(); 699 if (scope.frameOrdinal() >= m_pausedCallFrames.size())
728 return; 700 return Response::Error("Could not find call frame with given id");
729 }
730 if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
731 *errorString = "Could not find call frame with given id";
732 return;
733 }
734 701
735 if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI(); 702 if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
736 if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); 703 if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole();
737 704
738 v8::MaybeLocal<v8::Value> maybeResultValue = 705 v8::MaybeLocal<v8::Value> maybeResultValue =
739 m_pausedCallFrames[scope.frameOrdinal()]->evaluate( 706 m_pausedCallFrames[scope.frameOrdinal()]->evaluate(
740 toV8String(m_isolate, expression)); 707 toV8String(m_isolate, expression));
741 708
742 // Re-initialize after running client's code, as it could have destroyed 709 // Re-initialize after running client's code, as it could have destroyed
743 // context or session. 710 // context or session.
744 response = scope.initialize(); 711 response = scope.initialize();
745 if (!response.isSuccess()) { 712 if (!response.isSuccess()) return response;
746 *errorString = response.errorMessage(); 713 return scope.injectedScript()->wrapEvaluateResult(
747 return;
748 }
749 response = scope.injectedScript()->wrapEvaluateResult(
750 maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), 714 maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""),
751 returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result, 715 returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result,
752 exceptionDetails); 716 exceptionDetails);
753 if (!response.isSuccess()) *errorString = response.errorMessage();
754 } 717 }
755 718
756 void V8DebuggerAgentImpl::setVariableValue( 719 Response V8DebuggerAgentImpl::setVariableValue(
757 ErrorString* errorString, int scopeNumber, const String16& variableName, 720 int scopeNumber, const String16& variableName,
758 std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument, 721 std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument,
759 const String16& callFrameId) { 722 const String16& callFrameId) {
760 if (!checkEnabled(errorString)) return; 723 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
761 if (!assertPaused(errorString)) return; 724 if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
762 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 725 InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
763 callFrameId); 726 callFrameId);
764 Response response = scope.initialize(); 727 Response response = scope.initialize();
765 if (!response.isSuccess()) { 728 if (!response.isSuccess()) return response;
766 *errorString = response.errorMessage();
767 return;
768 }
769 v8::Local<v8::Value> newValue; 729 v8::Local<v8::Value> newValue;
770 response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(), 730 response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(),
771 &newValue); 731 &newValue);
772 if (!response.isSuccess()) { 732 if (!response.isSuccess()) return response;
773 *errorString = response.errorMessage();
774 return;
775 }
776 733
777 if (scope.frameOrdinal() >= m_pausedCallFrames.size()) { 734 if (scope.frameOrdinal() >= m_pausedCallFrames.size())
778 *errorString = "Could not find call frame with given id"; 735 return Response::Error("Could not find call frame with given id");
779 return;
780 }
781 v8::MaybeLocal<v8::Value> result = 736 v8::MaybeLocal<v8::Value> result =
782 m_pausedCallFrames[scope.frameOrdinal()]->setVariableValue( 737 m_pausedCallFrames[scope.frameOrdinal()]->setVariableValue(
783 scopeNumber, toV8String(m_isolate, variableName), newValue); 738 scopeNumber, toV8String(m_isolate, variableName), newValue);
784 if (scope.tryCatch().HasCaught() || result.IsEmpty()) { 739 if (scope.tryCatch().HasCaught() || result.IsEmpty())
785 *errorString = "Internal error"; 740 return Response::InternalError();
786 return; 741 return Response::OK();
787 }
788 } 742 }
789 743
790 void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString, 744 Response V8DebuggerAgentImpl::setAsyncCallStackDepth(int depth) {
791 int depth) { 745 if (!enabled()) return Response::Error(kDebuggerNotEnabled);
792 if (!checkEnabled(errorString)) return;
793 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, depth); 746 m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, depth);
794 m_debugger->setAsyncCallStackDepth(this, depth); 747 m_debugger->setAsyncCallStackDepth(this, depth);
748 return Response::OK();
795 } 749 }
796 750
797 void V8DebuggerAgentImpl::setBlackboxPatterns( 751 Response V8DebuggerAgentImpl::setBlackboxPatterns(
798 ErrorString* errorString,
799 std::unique_ptr<protocol::Array<String16>> patterns) { 752 std::unique_ptr<protocol::Array<String16>> patterns) {
800 if (!patterns->length()) { 753 if (!patterns->length()) {
801 m_blackboxPattern = nullptr; 754 m_blackboxPattern = nullptr;
802 m_state->remove(DebuggerAgentState::blackboxPattern); 755 m_state->remove(DebuggerAgentState::blackboxPattern);
803 return; 756 return Response::OK();
804 } 757 }
805 758
806 String16Builder patternBuilder; 759 String16Builder patternBuilder;
807 patternBuilder.append('('); 760 patternBuilder.append('(');
808 for (size_t i = 0; i < patterns->length() - 1; ++i) { 761 for (size_t i = 0; i < patterns->length() - 1; ++i) {
809 patternBuilder.append(patterns->get(i)); 762 patternBuilder.append(patterns->get(i));
810 patternBuilder.append("|"); 763 patternBuilder.append("|");
811 } 764 }
812 patternBuilder.append(patterns->get(patterns->length() - 1)); 765 patternBuilder.append(patterns->get(patterns->length() - 1));
813 patternBuilder.append(')'); 766 patternBuilder.append(')');
814 String16 pattern = patternBuilder.toString(); 767 String16 pattern = patternBuilder.toString();
815 if (!setBlackboxPattern(errorString, pattern)) return; 768 Response response = setBlackboxPattern(pattern);
769 if (!response.isSuccess()) return response;
816 m_state->setString(DebuggerAgentState::blackboxPattern, pattern); 770 m_state->setString(DebuggerAgentState::blackboxPattern, pattern);
771 return Response::OK();
817 } 772 }
818 773
819 bool V8DebuggerAgentImpl::setBlackboxPattern(ErrorString* errorString, 774 Response V8DebuggerAgentImpl::setBlackboxPattern(const String16& pattern) {
820 const String16& pattern) {
821 std::unique_ptr<V8Regex> regex(new V8Regex( 775 std::unique_ptr<V8Regex> regex(new V8Regex(
822 m_inspector, pattern, true /** caseSensitive */, false /** multiline */)); 776 m_inspector, pattern, true /** caseSensitive */, false /** multiline */));
823 if (!regex->isValid()) { 777 if (!regex->isValid())
824 *errorString = "Pattern parser error: " + regex->errorMessage(); 778 return Response::Error("Pattern parser error: " + regex->errorMessage());
825 return false;
826 }
827 m_blackboxPattern = std::move(regex); 779 m_blackboxPattern = std::move(regex);
828 return true; 780 return Response::OK();
829 } 781 }
830 782
831 void V8DebuggerAgentImpl::setBlackboxedRanges( 783 Response V8DebuggerAgentImpl::setBlackboxedRanges(
832 ErrorString* error, const String16& scriptId, 784 const String16& scriptId,
833 std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>> 785 std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
834 inPositions) { 786 inPositions) {
835 if (m_scripts.find(scriptId) == m_scripts.end()) { 787 if (m_scripts.find(scriptId) == m_scripts.end())
836 *error = "No script with passed id."; 788 return Response::Error("No script with passed id.");
837 return;
838 }
839 789
840 if (!inPositions->length()) { 790 if (!inPositions->length()) {
841 m_blackboxedPositions.erase(scriptId); 791 m_blackboxedPositions.erase(scriptId);
842 return; 792 return Response::OK();
843 } 793 }
844 794
845 std::vector<std::pair<int, int>> positions; 795 std::vector<std::pair<int, int>> positions;
846 positions.reserve(inPositions->length()); 796 positions.reserve(inPositions->length());
847 for (size_t i = 0; i < inPositions->length(); ++i) { 797 for (size_t i = 0; i < inPositions->length(); ++i) {
848 protocol::Debugger::ScriptPosition* position = inPositions->get(i); 798 protocol::Debugger::ScriptPosition* position = inPositions->get(i);
849 if (position->getLineNumber() < 0) { 799 if (position->getLineNumber() < 0)
850 *error = "Position missing 'line' or 'line' < 0."; 800 return Response::Error("Position missing 'line' or 'line' < 0.");
851 return; 801 if (position->getColumnNumber() < 0)
852 } 802 return Response::Error("Position missing 'column' or 'column' < 0.");
853 if (position->getColumnNumber() < 0) {
854 *error = "Position missing 'column' or 'column' < 0.";
855 return;
856 }
857 positions.push_back( 803 positions.push_back(
858 std::make_pair(position->getLineNumber(), position->getColumnNumber())); 804 std::make_pair(position->getLineNumber(), position->getColumnNumber()));
859 } 805 }
860 806
861 for (size_t i = 1; i < positions.size(); ++i) { 807 for (size_t i = 1; i < positions.size(); ++i) {
862 if (positions[i - 1].first < positions[i].first) continue; 808 if (positions[i - 1].first < positions[i].first) continue;
863 if (positions[i - 1].first == positions[i].first && 809 if (positions[i - 1].first == positions[i].first &&
864 positions[i - 1].second < positions[i].second) 810 positions[i - 1].second < positions[i].second)
865 continue; 811 continue;
866 *error = 812 return Response::Error(
867 "Input positions array is not sorted or contains duplicate values."; 813 "Input positions array is not sorted or contains duplicate values.");
868 return;
869 } 814 }
870 815
871 m_blackboxedPositions[scriptId] = positions; 816 m_blackboxedPositions[scriptId] = positions;
817 return Response::OK();
872 } 818 }
873 819
874 void V8DebuggerAgentImpl::willExecuteScript(int scriptId) { 820 void V8DebuggerAgentImpl::willExecuteScript(int scriptId) {
875 changeJavaScriptRecursionLevel(+1); 821 changeJavaScriptRecursionLevel(+1);
876 // Fast return. 822 // Fast return.
877 if (m_scheduledDebuggerStep != StepInto) return; 823 if (m_scheduledDebuggerStep != StepInto) return;
878 schedulePauseOnNextStatementIfSteppingInto(); 824 schedulePauseOnNextStatementIfSteppingInto();
879 } 825 }
880 826
881 void V8DebuggerAgentImpl::didExecuteScript() { 827 void V8DebuggerAgentImpl::didExecuteScript() {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 // from the old StepFrame. 860 // from the old StepFrame.
915 m_skippedStepFrameCount = 0; 861 m_skippedStepFrameCount = 0;
916 if (m_scheduledDebuggerStep == NoStep) 862 if (m_scheduledDebuggerStep == NoStep)
917 m_debugger->clearStepping(); 863 m_debugger->clearStepping();
918 else if (m_scheduledDebuggerStep == StepOut) 864 else if (m_scheduledDebuggerStep == StepOut)
919 m_skipNextDebuggerStepOut = true; 865 m_skipNextDebuggerStepOut = true;
920 } 866 }
921 } 867 }
922 } 868 }
923 869
924 std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames( 870 Response V8DebuggerAgentImpl::currentCallFrames(
925 ErrorString* errorString) { 871 std::unique_ptr<Array<CallFrame>>* result) {
926 if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) 872 if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) {
927 return Array<CallFrame>::create(); 873 *result = Array<CallFrame>::create();
874 return Response::OK();
875 }
928 v8::HandleScope handles(m_isolate); 876 v8::HandleScope handles(m_isolate);
929 v8::Local<v8::Context> debuggerContext = 877 v8::Local<v8::Context> debuggerContext =
930 v8::DebugInterface::GetDebugContext(m_isolate); 878 v8::DebugInterface::GetDebugContext(m_isolate);
931 v8::Context::Scope contextScope(debuggerContext); 879 v8::Context::Scope contextScope(debuggerContext);
932 880
933 v8::Local<v8::Array> objects = v8::Array::New(m_isolate); 881 v8::Local<v8::Array> objects = v8::Array::New(m_isolate);
934 882
935 for (size_t frameOrdinal = 0; frameOrdinal < m_pausedCallFrames.size(); 883 for (size_t frameOrdinal = 0; frameOrdinal < m_pausedCallFrames.size();
936 ++frameOrdinal) { 884 ++frameOrdinal) {
937 const std::unique_ptr<JavaScriptCallFrame>& currentCallFrame = 885 const std::unique_ptr<JavaScriptCallFrame>& currentCallFrame =
938 m_pausedCallFrames[frameOrdinal]; 886 m_pausedCallFrames[frameOrdinal];
939 887
940 v8::Local<v8::Object> details = currentCallFrame->details(); 888 v8::Local<v8::Object> details = currentCallFrame->details();
941 if (hasInternalError(errorString, details.IsEmpty())) 889 if (details.IsEmpty()) return Response::InternalError();
942 return Array<CallFrame>::create();
943 890
944 int contextId = currentCallFrame->contextId(); 891 int contextId = currentCallFrame->contextId();
945 892
946 InjectedScript* injectedScript = nullptr; 893 InjectedScript* injectedScript = nullptr;
947 if (contextId) m_session->findInjectedScript(contextId, injectedScript); 894 if (contextId) m_session->findInjectedScript(contextId, injectedScript);
948 895
949 String16 callFrameId = 896 String16 callFrameId =
950 RemoteCallFrameId::serialize(contextId, static_cast<int>(frameOrdinal)); 897 RemoteCallFrameId::serialize(contextId, static_cast<int>(frameOrdinal));
951 if (hasInternalError( 898 if (!details
952 errorString, 899 ->Set(debuggerContext,
953 !details 900 toV8StringInternalized(m_isolate, "callFrameId"),
954 ->Set(debuggerContext, 901 toV8String(m_isolate, callFrameId))
955 toV8StringInternalized(m_isolate, "callFrameId"), 902 .FromMaybe(false)) {
956 toV8String(m_isolate, callFrameId)) 903 return Response::InternalError();
957 .FromMaybe(false))) 904 }
958 return Array<CallFrame>::create();
959 905
960 if (injectedScript) { 906 if (injectedScript) {
961 v8::Local<v8::Value> scopeChain; 907 v8::Local<v8::Value> scopeChain;
962 if (hasInternalError( 908 if (!details
963 errorString, 909 ->Get(debuggerContext,
964 !details->Get(debuggerContext, 910 toV8StringInternalized(m_isolate, "scopeChain"))
965 toV8StringInternalized(m_isolate, "scopeChain")) 911 .ToLocal(&scopeChain) ||
966 .ToLocal(&scopeChain) || 912 !scopeChain->IsArray()) {
967 !scopeChain->IsArray())) 913 return Response::InternalError();
968 return Array<CallFrame>::create(); 914 }
969 v8::Local<v8::Array> scopeChainArray = scopeChain.As<v8::Array>(); 915 v8::Local<v8::Array> scopeChainArray = scopeChain.As<v8::Array>();
970 Response response = injectedScript->wrapPropertyInArray( 916 Response response = injectedScript->wrapPropertyInArray(
971 scopeChainArray, toV8StringInternalized(m_isolate, "object"), 917 scopeChainArray, toV8StringInternalized(m_isolate, "object"),
972 backtraceObjectGroup); 918 kBacktraceObjectGroup);
973 if (!response.isSuccess()) { 919 if (!response.isSuccess()) return response;
974 *errorString = response.errorMessage();
975 return Array<CallFrame>::create();
976 }
977 response = injectedScript->wrapObjectProperty( 920 response = injectedScript->wrapObjectProperty(
978 details, toV8StringInternalized(m_isolate, "this"), 921 details, toV8StringInternalized(m_isolate, "this"),
979 backtraceObjectGroup); 922 kBacktraceObjectGroup);
980 if (!response.isSuccess()) { 923 if (!response.isSuccess()) return response;
981 *errorString = response.errorMessage();
982 return Array<CallFrame>::create();
983 }
984 if (details 924 if (details
985 ->Has(debuggerContext, 925 ->Has(debuggerContext,
986 toV8StringInternalized(m_isolate, "returnValue")) 926 toV8StringInternalized(m_isolate, "returnValue"))
987 .FromMaybe(false)) { 927 .FromMaybe(false)) {
988 response = injectedScript->wrapObjectProperty( 928 response = injectedScript->wrapObjectProperty(
989 details, toV8StringInternalized(m_isolate, "returnValue"), 929 details, toV8StringInternalized(m_isolate, "returnValue"),
990 backtraceObjectGroup); 930 kBacktraceObjectGroup);
991 if (!response.isSuccess()) { 931 if (!response.isSuccess()) return response;
992 *errorString = response.errorMessage();
993 return Array<CallFrame>::create();
994 }
995 } 932 }
996 } else { 933 } else {
997 if (hasInternalError(errorString, !details 934 if (!details
998 ->Set(debuggerContext, 935 ->Set(debuggerContext,
999 toV8StringInternalized( 936 toV8StringInternalized(m_isolate, "scopeChain"),
1000 m_isolate, "scopeChain"), 937 v8::Array::New(m_isolate, 0))
1001 v8::Array::New(m_isolate, 0)) 938 .FromMaybe(false)) {
1002 .FromMaybe(false))) 939 return Response::InternalError();
1003 return Array<CallFrame>::create(); 940 }
1004 v8::Local<v8::Object> remoteObject = v8::Object::New(m_isolate); 941 v8::Local<v8::Object> remoteObject = v8::Object::New(m_isolate);
1005 if (hasInternalError( 942 if (!remoteObject
1006 errorString, 943 ->Set(debuggerContext, toV8StringInternalized(m_isolate, "type"),
1007 !remoteObject 944 toV8StringInternalized(m_isolate, "undefined"))
1008 ->Set(debuggerContext, 945 .FromMaybe(false)) {
1009 toV8StringInternalized(m_isolate, "type"), 946 return Response::InternalError();
1010 toV8StringInternalized(m_isolate, "undefined")) 947 }
1011 .FromMaybe(false))) 948 if (!details
1012 return Array<CallFrame>::create(); 949 ->Set(debuggerContext, toV8StringInternalized(m_isolate, "this"),
1013 if (hasInternalError(errorString, 950 remoteObject)
1014 !details 951 .FromMaybe(false)) {
1015 ->Set(debuggerContext, 952 return Response::InternalError();
1016 toV8StringInternalized(m_isolate, "this"), 953 }
1017 remoteObject) 954 if (!details
1018 .FromMaybe(false))) 955 ->Delete(debuggerContext,
1019 return Array<CallFrame>::create(); 956 toV8StringInternalized(m_isolate, "returnValue"))
1020 if (hasInternalError( 957 .FromMaybe(false)) {
1021 errorString, 958 return Response::InternalError();
1022 !details 959 }
1023 ->Delete(debuggerContext,
1024 toV8StringInternalized(m_isolate, "returnValue"))
1025 .FromMaybe(false)))
1026 return Array<CallFrame>::create();
1027 } 960 }
1028 961
1029 if (hasInternalError( 962 if (!objects->Set(debuggerContext, static_cast<int>(frameOrdinal), details)
1030 errorString, 963 .FromMaybe(false)) {
1031 !objects 964 return Response::InternalError();
1032 ->Set(debuggerContext, static_cast<int>(frameOrdinal), details) 965 }
1033 .FromMaybe(false)))
1034 return Array<CallFrame>::create();
1035 } 966 }
1036 967
1037 std::unique_ptr<protocol::Value> protocolValue; 968 std::unique_ptr<protocol::Value> protocolValue;
1038 Response response = toProtocolValue(debuggerContext, objects, &protocolValue); 969 Response response = toProtocolValue(debuggerContext, objects, &protocolValue);
1039 if (!response.isSuccess()) return Array<CallFrame>::create(); 970 if (!response.isSuccess()) return response;
1040 protocol::ErrorSupport errorSupport; 971 protocol::ErrorSupport errorSupport;
1041 std::unique_ptr<Array<CallFrame>> callFrames = 972 *result = Array<CallFrame>::parse(protocolValue.get(), &errorSupport);
1042 Array<CallFrame>::parse(protocolValue.get(), &errorSupport); 973 if (!*result) return Response::Error(errorSupport.errors());
1043 if (hasInternalError(errorString, !callFrames)) 974 return Response::OK();
1044 return Array<CallFrame>::create();
1045 return callFrames;
1046 } 975 }
1047 976
1048 std::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() { 977 std::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() {
1049 if (m_pausedContext.IsEmpty()) return nullptr; 978 if (m_pausedContext.IsEmpty()) return nullptr;
1050 V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain(); 979 V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain();
1051 return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger) 980 return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger)
1052 : nullptr; 981 : nullptr;
1053 } 982 }
1054 983
1055 void V8DebuggerAgentImpl::didParseSource( 984 void V8DebuggerAgentImpl::didParseSource(
1056 std::unique_ptr<V8DebuggerScript> script, bool success) { 985 std::unique_ptr<V8DebuggerScript> script, bool success) {
1057 v8::HandleScope handles(m_isolate); 986 v8::HandleScope handles(m_isolate);
1058 String16 scriptSource = toProtocolString(script->source(m_isolate)); 987 String16 scriptSource = toProtocolString(script->source(m_isolate));
1059 if (!success) script->setSourceURL(findSourceURL(scriptSource, false)); 988 if (!success) script->setSourceURL(findSourceURL(scriptSource, false));
1060 if (!success) 989 if (!success)
1061 script->setSourceMappingURL(findSourceMapURL(scriptSource, false)); 990 script->setSourceMappingURL(findSourceMapURL(scriptSource, false));
1062 991
1063 std::unique_ptr<protocol::DictionaryValue> executionContextAuxData; 992 std::unique_ptr<protocol::DictionaryValue> executionContextAuxData;
1064 if (!script->executionContextAuxData().isEmpty()) 993 if (!script->executionContextAuxData().isEmpty())
1065 executionContextAuxData = protocol::DictionaryValue::cast( 994 executionContextAuxData = protocol::DictionaryValue::cast(
1066 protocol::parseJSON(script->executionContextAuxData())); 995 protocol::parseJSON(script->executionContextAuxData()));
1067 bool isLiveEdit = script->isLiveEdit(); 996 bool isLiveEdit = script->isLiveEdit();
1068 bool hasSourceURL = script->hasSourceURL(); 997 bool hasSourceURL = script->hasSourceURL();
1069 String16 scriptId = script->scriptId(); 998 String16 scriptId = script->scriptId();
1070 String16 scriptURL = script->sourceURL(); 999 String16 scriptURL = script->sourceURL();
1071 1000
1072 const Maybe<String16>& sourceMapURLParam = script->sourceMappingURL(); 1001 Maybe<String16> sourceMapURLParam = script->sourceMappingURL();
1073 const Maybe<protocol::DictionaryValue>& executionContextAuxDataParam( 1002 Maybe<protocol::DictionaryValue> executionContextAuxDataParam(
1074 std::move(executionContextAuxData)); 1003 std::move(executionContextAuxData));
1075 const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; 1004 const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
1076 const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; 1005 const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr;
1077 if (success) 1006 if (success)
1078 m_frontend.scriptParsed( 1007 m_frontend.scriptParsed(
1079 scriptId, scriptURL, script->startLine(), script->startColumn(), 1008 scriptId, scriptURL, script->startLine(), script->startColumn(),
1080 script->endLine(), script->endColumn(), script->executionContextId(), 1009 script->endLine(), script->endColumn(), script->executionContextId(),
1081 script->hash(), executionContextAuxDataParam, isLiveEditParam, 1010 script->hash(), std::move(executionContextAuxDataParam),
1082 sourceMapURLParam, hasSourceURLParam); 1011 isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam);
1083 else 1012 else
1084 m_frontend.scriptFailedToParse( 1013 m_frontend.scriptFailedToParse(
1085 scriptId, scriptURL, script->startLine(), script->startColumn(), 1014 scriptId, scriptURL, script->startLine(), script->startColumn(),
1086 script->endLine(), script->endColumn(), script->executionContextId(), 1015 script->endLine(), script->endColumn(), script->executionContextId(),
1087 script->hash(), executionContextAuxDataParam, sourceMapURLParam, 1016 script->hash(), std::move(executionContextAuxDataParam),
1088 hasSourceURLParam); 1017 std::move(sourceMapURLParam), hasSourceURLParam);
1089 1018
1090 m_scripts[scriptId] = std::move(script); 1019 m_scripts[scriptId] = std::move(script);
1091 1020
1092 if (scriptURL.isEmpty() || !success) return; 1021 if (scriptURL.isEmpty() || !success) return;
1093 1022
1094 protocol::DictionaryValue* breakpointsCookie = 1023 protocol::DictionaryValue* breakpointsCookie =
1095 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); 1024 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
1096 if (!breakpointsCookie) return; 1025 if (!breakpointsCookie) return;
1097 1026
1098 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { 1027 for (size_t i = 0; i < breakpointsCookie->size(); ++i) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 if (!exception.IsEmpty()) { 1082 if (!exception.IsEmpty()) {
1154 InjectedScript* injectedScript = nullptr; 1083 InjectedScript* injectedScript = nullptr;
1155 m_session->findInjectedScript(V8Debugger::contextId(context), 1084 m_session->findInjectedScript(V8Debugger::contextId(context),
1156 injectedScript); 1085 injectedScript);
1157 if (injectedScript) { 1086 if (injectedScript) {
1158 m_breakReason = 1087 m_breakReason =
1159 isPromiseRejection 1088 isPromiseRejection
1160 ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection 1089 ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
1161 : protocol::Debugger::Paused::ReasonEnum::Exception; 1090 : protocol::Debugger::Paused::ReasonEnum::Exception;
1162 std::unique_ptr<protocol::Runtime::RemoteObject> obj; 1091 std::unique_ptr<protocol::Runtime::RemoteObject> obj;
1163 injectedScript->wrapObject(exception, backtraceObjectGroup, false, false, 1092 injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false,
1164 &obj); 1093 &obj);
1165 m_breakAuxData = obj ? obj->serialize() : nullptr; 1094 m_breakAuxData = obj ? obj->serialize() : nullptr;
1166 // m_breakAuxData might be null after this. 1095 // m_breakAuxData might be null after this.
1167 } 1096 }
1168 } 1097 }
1169 1098
1170 std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create(); 1099 std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create();
1171 1100
1172 for (const auto& point : hitBreakpoints) { 1101 for (const auto& point : hitBreakpoints) {
1173 DebugServerBreakpointToBreakpointIdAndSourceMap::iterator 1102 DebugServerBreakpointToBreakpointIdAndSourceMap::iterator
1174 breakpointIterator = m_serverBreakpoints.find(point); 1103 breakpointIterator = m_serverBreakpoints.find(point);
1175 if (breakpointIterator != m_serverBreakpoints.end()) { 1104 if (breakpointIterator != m_serverBreakpoints.end()) {
1176 const String16& localId = breakpointIterator->second.first; 1105 const String16& localId = breakpointIterator->second.first;
1177 hitBreakpointIds->addItem(localId); 1106 hitBreakpointIds->addItem(localId);
1178 1107
1179 BreakpointSource source = breakpointIterator->second.second; 1108 BreakpointSource source = breakpointIterator->second.second;
1180 if (m_breakReason == protocol::Debugger::Paused::ReasonEnum::Other && 1109 if (m_breakReason == protocol::Debugger::Paused::ReasonEnum::Other &&
1181 source == DebugCommandBreakpointSource) 1110 source == DebugCommandBreakpointSource)
1182 m_breakReason = protocol::Debugger::Paused::ReasonEnum::DebugCommand; 1111 m_breakReason = protocol::Debugger::Paused::ReasonEnum::DebugCommand;
1183 } 1112 }
1184 } 1113 }
1185 1114
1186 ErrorString errorString; 1115 std::unique_ptr<Array<CallFrame>> protocolCallFrames;
1187 m_frontend.paused(currentCallFrames(&errorString), m_breakReason, 1116 Response response = currentCallFrames(&protocolCallFrames);
1117 if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create();
1118 m_frontend.paused(std::move(protocolCallFrames), m_breakReason,
1188 std::move(m_breakAuxData), std::move(hitBreakpointIds), 1119 std::move(m_breakAuxData), std::move(hitBreakpointIds),
1189 currentAsyncStackTrace()); 1120 currentAsyncStackTrace());
1190 m_scheduledDebuggerStep = NoStep; 1121 m_scheduledDebuggerStep = NoStep;
1191 m_javaScriptPauseScheduled = false; 1122 m_javaScriptPauseScheduled = false;
1192 m_steppingFromFramework = false; 1123 m_steppingFromFramework = false;
1193 m_pausingOnNativeEvent = false; 1124 m_pausingOnNativeEvent = false;
1194 m_skippedStepFrameCount = 0; 1125 m_skippedStepFrameCount = 0;
1195 m_recursionLevelForStepFrame = 0; 1126 m_recursionLevelForStepFrame = 0;
1196 1127
1197 if (!m_continueToLocationBreakpointId.isEmpty()) { 1128 if (!m_continueToLocationBreakpointId.isEmpty()) {
(...skipping 29 matching lines...) Expand all
1227 void V8DebuggerAgentImpl::breakProgramOnException( 1158 void V8DebuggerAgentImpl::breakProgramOnException(
1228 const String16& breakReason, 1159 const String16& breakReason,
1229 std::unique_ptr<protocol::DictionaryValue> data) { 1160 std::unique_ptr<protocol::DictionaryValue> data) {
1230 if (!enabled() || 1161 if (!enabled() ||
1231 m_debugger->getPauseOnExceptionsState() == 1162 m_debugger->getPauseOnExceptionsState() ==
1232 v8::DebugInterface::NoBreakOnException) 1163 v8::DebugInterface::NoBreakOnException)
1233 return; 1164 return;
1234 breakProgram(breakReason, std::move(data)); 1165 breakProgram(breakReason, std::move(data));
1235 } 1166 }
1236 1167
1237 bool V8DebuggerAgentImpl::assertPaused(ErrorString* errorString) {
1238 if (m_pausedContext.IsEmpty()) {
1239 *errorString = "Can only perform operation while paused.";
1240 return false;
1241 }
1242 return true;
1243 }
1244
1245 void V8DebuggerAgentImpl::clearBreakDetails() { 1168 void V8DebuggerAgentImpl::clearBreakDetails() {
1246 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other; 1169 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other;
1247 m_breakAuxData = nullptr; 1170 m_breakAuxData = nullptr;
1248 } 1171 }
1249 1172
1250 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, 1173 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId,
1251 int lineNumber, int columnNumber, 1174 int lineNumber, int columnNumber,
1252 BreakpointSource source, 1175 BreakpointSource source,
1253 const String16& condition) { 1176 const String16& condition) {
1254 String16 breakpointId = 1177 String16 breakpointId =
1255 generateBreakpointId(scriptId, lineNumber, columnNumber, source); 1178 generateBreakpointId(scriptId, lineNumber, columnNumber, source);
1256 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); 1179 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
1257 resolveBreakpoint(breakpointId, scriptId, breakpoint, source); 1180 resolveBreakpoint(breakpointId, scriptId, breakpoint, source);
1258 } 1181 }
1259 1182
1260 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, 1183 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId,
1261 int lineNumber, int columnNumber, 1184 int lineNumber, int columnNumber,
1262 BreakpointSource source) { 1185 BreakpointSource source) {
1263 removeBreakpoint( 1186 removeBreakpointImpl(
1264 generateBreakpointId(scriptId, lineNumber, columnNumber, source)); 1187 generateBreakpointId(scriptId, lineNumber, columnNumber, source));
1265 } 1188 }
1266 1189
1267 void V8DebuggerAgentImpl::reset() { 1190 void V8DebuggerAgentImpl::reset() {
1268 if (!enabled()) return; 1191 if (!enabled()) return;
1269 m_scheduledDebuggerStep = NoStep; 1192 m_scheduledDebuggerStep = NoStep;
1270 m_scripts.clear(); 1193 m_scripts.clear();
1271 m_blackboxedPositions.clear(); 1194 m_blackboxedPositions.clear();
1272 m_breakpointIdToDebuggerBreakpointIds.clear(); 1195 m_breakpointIdToDebuggerBreakpointIds.clear();
1273 } 1196 }
1274 1197
1275 } // namespace v8_inspector 1198 } // namespace v8_inspector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698