OLD | NEW |
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 break; | 67 break; |
68 case V8DebuggerAgentImpl::DebugCommandBreakpointSource: | 68 case V8DebuggerAgentImpl::DebugCommandBreakpointSource: |
69 return ":debug"; | 69 return ":debug"; |
70 case V8DebuggerAgentImpl::MonitorCommandBreakpointSource: | 70 case V8DebuggerAgentImpl::MonitorCommandBreakpointSource: |
71 return ":monitor"; | 71 return ":monitor"; |
72 } | 72 } |
73 return String16(); | 73 return String16(); |
74 } | 74 } |
75 | 75 |
76 static String16 generateBreakpointId( | 76 static String16 generateBreakpointId( |
77 const String16& scriptId, int lineNumber, int columnNumber, | 77 const ScriptBreakpoint& breakpoint, |
78 V8DebuggerAgentImpl::BreakpointSource source) { | 78 V8DebuggerAgentImpl::BreakpointSource source) { |
79 String16Builder builder; | 79 String16Builder builder; |
80 builder.append(scriptId); | 80 builder.append(breakpoint.script_id); |
81 builder.append(':'); | 81 builder.append(':'); |
82 builder.appendNumber(lineNumber); | 82 builder.appendNumber(breakpoint.line_number); |
83 builder.append(':'); | 83 builder.append(':'); |
84 builder.appendNumber(columnNumber); | 84 builder.appendNumber(breakpoint.column_number); |
85 builder.append(breakpointIdSuffix(source)); | 85 builder.append(breakpointIdSuffix(source)); |
86 return builder.toString(); | 86 return builder.toString(); |
87 } | 87 } |
88 | 88 |
89 static bool positionComparator(const std::pair<int, int>& a, | 89 static bool positionComparator(const std::pair<int, int>& a, |
90 const std::pair<int, int>& b) { | 90 const std::pair<int, int>& b) { |
91 if (a.first != b.first) return a.first < b.first; | 91 if (a.first != b.first) return a.first < b.first; |
92 return a.second < b.second; | 92 return a.second < b.second; |
93 } | 93 } |
94 | 94 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, | 284 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, |
285 std::move(newValue)); | 285 std::move(newValue)); |
286 } | 286 } |
287 if (breakpointsCookie->get(breakpointId)) | 287 if (breakpointsCookie->get(breakpointId)) |
288 return Response::Error("Breakpoint at specified location already exists."); | 288 return Response::Error("Breakpoint at specified location already exists."); |
289 | 289 |
290 breakpointsCookie->setObject( | 290 breakpointsCookie->setObject( |
291 breakpointId, buildObjectForBreakpointCookie( | 291 breakpointId, buildObjectForBreakpointCookie( |
292 url, lineNumber, columnNumber, condition, isRegex)); | 292 url, lineNumber, columnNumber, condition, isRegex)); |
293 | 293 |
294 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 294 ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition); |
295 for (const auto& script : m_scripts) { | 295 for (const auto& script : m_scripts) { |
296 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) | 296 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) |
297 continue; | 297 continue; |
298 std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( | 298 breakpoint.script_id = script.first; |
299 breakpointId, script.first, breakpoint, UserBreakpointSource); | 299 std::unique_ptr<protocol::Debugger::Location> location = |
| 300 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); |
300 if (location) (*locations)->addItem(std::move(location)); | 301 if (location) (*locations)->addItem(std::move(location)); |
301 } | 302 } |
302 | 303 |
303 *outBreakpointId = breakpointId; | 304 *outBreakpointId = breakpointId; |
304 return Response::OK(); | 305 return Response::OK(); |
305 } | 306 } |
306 | 307 |
307 Response V8DebuggerAgentImpl::setBreakpoint( | 308 Response V8DebuggerAgentImpl::setBreakpoint( |
308 std::unique_ptr<protocol::Debugger::Location> location, | 309 std::unique_ptr<protocol::Debugger::Location> location, |
309 Maybe<String16> optionalCondition, String16* outBreakpointId, | 310 Maybe<String16> optionalCondition, String16* outBreakpointId, |
310 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { | 311 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { |
311 String16 scriptId = location->getScriptId(); | 312 ScriptBreakpoint breakpoint( |
312 int lineNumber = location->getLineNumber(); | 313 location->getScriptId(), location->getLineNumber(), |
313 int columnNumber = location->getColumnNumber(0); | 314 location->getColumnNumber(0), optionalCondition.fromMaybe(String16())); |
314 | 315 |
315 String16 condition = optionalCondition.fromMaybe(""); | 316 String16 breakpointId = |
316 | 317 generateBreakpointId(breakpoint, UserBreakpointSource); |
317 String16 breakpointId = generateBreakpointId( | |
318 scriptId, lineNumber, columnNumber, UserBreakpointSource); | |
319 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != | 318 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != |
320 m_breakpointIdToDebuggerBreakpointIds.end()) { | 319 m_breakpointIdToDebuggerBreakpointIds.end()) { |
321 return Response::Error("Breakpoint at specified location already exists."); | 320 return Response::Error("Breakpoint at specified location already exists."); |
322 } | 321 } |
323 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 322 *actualLocation = |
324 *actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, | 323 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); |
325 UserBreakpointSource); | |
326 if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); | 324 if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); |
327 *outBreakpointId = breakpointId; | 325 *outBreakpointId = breakpointId; |
328 return Response::OK(); | 326 return Response::OK(); |
329 } | 327 } |
330 | 328 |
331 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { | 329 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { |
332 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 330 if (!enabled()) return Response::Error(kDebuggerNotEnabled); |
333 protocol::DictionaryValue* breakpointsCookie = | 331 protocol::DictionaryValue* breakpointsCookie = |
334 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); | 332 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); |
335 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); | 333 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 } | 396 } |
399 | 397 |
400 Response V8DebuggerAgentImpl::continueToLocation( | 398 Response V8DebuggerAgentImpl::continueToLocation( |
401 std::unique_ptr<protocol::Debugger::Location> location) { | 399 std::unique_ptr<protocol::Debugger::Location> location) { |
402 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 400 if (!enabled()) return Response::Error(kDebuggerNotEnabled); |
403 if (!m_continueToLocationBreakpointId.isEmpty()) { | 401 if (!m_continueToLocationBreakpointId.isEmpty()) { |
404 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); | 402 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); |
405 m_continueToLocationBreakpointId = ""; | 403 m_continueToLocationBreakpointId = ""; |
406 } | 404 } |
407 | 405 |
408 String16 scriptId = location->getScriptId(); | 406 ScriptBreakpoint breakpoint(location->getScriptId(), |
409 int lineNumber = location->getLineNumber(); | 407 location->getLineNumber(), |
410 int columnNumber = location->getColumnNumber(0); | 408 location->getColumnNumber(0), String16()); |
411 | 409 |
412 ScriptBreakpoint breakpoint(lineNumber, columnNumber, ""); | |
413 m_continueToLocationBreakpointId = m_debugger->setBreakpoint( | 410 m_continueToLocationBreakpointId = m_debugger->setBreakpoint( |
414 scriptId, breakpoint, &lineNumber, &columnNumber); | 411 breakpoint, &breakpoint.line_number, &breakpoint.column_number); |
| 412 // TODO(kozyatinskiy): Return actual line and column number. |
415 return resume(); | 413 return resume(); |
416 } | 414 } |
417 | 415 |
418 bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { | 416 bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { |
419 DCHECK(enabled()); | 417 DCHECK(enabled()); |
420 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(); | 418 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(); |
421 for (size_t index = 0; index < callFrames.size(); ++index) { | 419 for (size_t index = 0; index < callFrames.size(); ++index) { |
422 if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) | 420 if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) |
423 return false; | 421 return false; |
424 } | 422 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut; | 484 if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut; |
487 | 485 |
488 if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1; | 486 if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1; |
489 | 487 |
490 ++m_skippedStepFrameCount; | 488 ++m_skippedStepFrameCount; |
491 return RequestStepFrame; | 489 return RequestStepFrame; |
492 } | 490 } |
493 | 491 |
494 std::unique_ptr<protocol::Debugger::Location> | 492 std::unique_ptr<protocol::Debugger::Location> |
495 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, | 493 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, |
496 const String16& scriptId, | |
497 const ScriptBreakpoint& breakpoint, | 494 const ScriptBreakpoint& breakpoint, |
498 BreakpointSource source) { | 495 BreakpointSource source) { |
499 DCHECK(enabled()); | 496 DCHECK(enabled()); |
500 // FIXME: remove these checks once crbug.com/520702 is resolved. | 497 // FIXME: remove these checks once crbug.com/520702 is resolved. |
501 CHECK(!breakpointId.isEmpty()); | 498 CHECK(!breakpointId.isEmpty()); |
502 CHECK(!scriptId.isEmpty()); | 499 CHECK(!breakpoint.script_id.isEmpty()); |
503 ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); | 500 ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id); |
504 if (scriptIterator == m_scripts.end()) return nullptr; | 501 if (scriptIterator == m_scripts.end()) return nullptr; |
505 if (breakpoint.lineNumber < scriptIterator->second->startLine() || | 502 if (breakpoint.line_number < scriptIterator->second->startLine() || |
506 scriptIterator->second->endLine() < breakpoint.lineNumber) | 503 scriptIterator->second->endLine() < breakpoint.line_number) |
507 return nullptr; | 504 return nullptr; |
508 | 505 |
509 int actualLineNumber; | 506 int actualLineNumber; |
510 int actualColumnNumber; | 507 int actualColumnNumber; |
511 String16 debuggerBreakpointId = m_debugger->setBreakpoint( | 508 String16 debuggerBreakpointId = m_debugger->setBreakpoint( |
512 scriptId, breakpoint, &actualLineNumber, &actualColumnNumber); | 509 breakpoint, &actualLineNumber, &actualColumnNumber); |
513 if (debuggerBreakpointId.isEmpty()) return nullptr; | 510 if (debuggerBreakpointId.isEmpty()) return nullptr; |
514 | 511 |
515 m_serverBreakpoints[debuggerBreakpointId] = | 512 m_serverBreakpoints[debuggerBreakpointId] = |
516 std::make_pair(breakpointId, source); | 513 std::make_pair(breakpointId, source); |
517 CHECK(!breakpointId.isEmpty()); | 514 CHECK(!breakpointId.isEmpty()); |
518 | 515 |
519 m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back( | 516 m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back( |
520 debuggerBreakpointId); | 517 debuggerBreakpointId); |
521 return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber); | 518 return buildProtocolLocation(breakpoint.script_id, actualLineNumber, |
| 519 actualColumnNumber); |
522 } | 520 } |
523 | 521 |
524 Response V8DebuggerAgentImpl::searchInContent( | 522 Response V8DebuggerAgentImpl::searchInContent( |
525 const String16& scriptId, const String16& query, | 523 const String16& scriptId, const String16& query, |
526 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, | 524 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, |
527 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { | 525 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { |
528 v8::HandleScope handles(m_isolate); | 526 v8::HandleScope handles(m_isolate); |
529 ScriptsMap::iterator it = m_scripts.find(scriptId); | 527 ScriptsMap::iterator it = m_scripts.find(scriptId); |
530 if (it == m_scripts.end()) | 528 if (it == m_scripts.end()) |
531 return Response::Error("No script for id: " + scriptId); | 529 return Response::Error("No script for id: " + scriptId); |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { | 1066 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { |
1069 auto cookie = breakpointsCookie->at(i); | 1067 auto cookie = breakpointsCookie->at(i); |
1070 protocol::DictionaryValue* breakpointObject = | 1068 protocol::DictionaryValue* breakpointObject = |
1071 protocol::DictionaryValue::cast(cookie.second); | 1069 protocol::DictionaryValue::cast(cookie.second); |
1072 bool isRegex; | 1070 bool isRegex; |
1073 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); | 1071 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); |
1074 String16 url; | 1072 String16 url; |
1075 breakpointObject->getString(DebuggerAgentState::url, &url); | 1073 breakpointObject->getString(DebuggerAgentState::url, &url); |
1076 if (!matches(m_inspector, scriptURL, url, isRegex)) continue; | 1074 if (!matches(m_inspector, scriptURL, url, isRegex)) continue; |
1077 ScriptBreakpoint breakpoint; | 1075 ScriptBreakpoint breakpoint; |
| 1076 breakpoint.script_id = scriptId; |
1078 breakpointObject->getInteger(DebuggerAgentState::lineNumber, | 1077 breakpointObject->getInteger(DebuggerAgentState::lineNumber, |
1079 &breakpoint.lineNumber); | 1078 &breakpoint.line_number); |
1080 breakpointObject->getInteger(DebuggerAgentState::columnNumber, | 1079 breakpointObject->getInteger(DebuggerAgentState::columnNumber, |
1081 &breakpoint.columnNumber); | 1080 &breakpoint.column_number); |
1082 breakpointObject->getString(DebuggerAgentState::condition, | 1081 breakpointObject->getString(DebuggerAgentState::condition, |
1083 &breakpoint.condition); | 1082 &breakpoint.condition); |
1084 std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( | 1083 std::unique_ptr<protocol::Debugger::Location> location = |
1085 cookie.first, scriptId, breakpoint, UserBreakpointSource); | 1084 resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource); |
1086 if (location) | 1085 if (location) |
1087 m_frontend.breakpointResolved(cookie.first, std::move(location)); | 1086 m_frontend.breakpointResolved(cookie.first, std::move(location)); |
1088 } | 1087 } |
1089 } | 1088 } |
1090 | 1089 |
1091 V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause( | 1090 V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause( |
1092 v8::Local<v8::Context> context, v8::Local<v8::Value> exception, | 1091 v8::Local<v8::Context> context, v8::Local<v8::Value> exception, |
1093 const std::vector<String16>& hitBreakpoints, bool isPromiseRejection, | 1092 const std::vector<String16>& hitBreakpoints, bool isPromiseRejection, |
1094 bool isUncaught) { | 1093 bool isUncaught) { |
1095 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1); | 1094 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 | 1213 |
1215 void V8DebuggerAgentImpl::clearBreakDetails() { | 1214 void V8DebuggerAgentImpl::clearBreakDetails() { |
1216 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other; | 1215 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other; |
1217 m_breakAuxData = nullptr; | 1216 m_breakAuxData = nullptr; |
1218 } | 1217 } |
1219 | 1218 |
1220 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, | 1219 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, |
1221 int lineNumber, int columnNumber, | 1220 int lineNumber, int columnNumber, |
1222 BreakpointSource source, | 1221 BreakpointSource source, |
1223 const String16& condition) { | 1222 const String16& condition) { |
1224 String16 breakpointId = | 1223 ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition); |
1225 generateBreakpointId(scriptId, lineNumber, columnNumber, source); | 1224 String16 breakpointId = generateBreakpointId(breakpoint, source); |
1226 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 1225 resolveBreakpoint(breakpointId, breakpoint, source); |
1227 resolveBreakpoint(breakpointId, scriptId, breakpoint, source); | |
1228 } | 1226 } |
1229 | 1227 |
1230 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, | 1228 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, |
1231 int lineNumber, int columnNumber, | 1229 int lineNumber, int columnNumber, |
1232 BreakpointSource source) { | 1230 BreakpointSource source) { |
1233 removeBreakpointImpl( | 1231 removeBreakpointImpl(generateBreakpointId( |
1234 generateBreakpointId(scriptId, lineNumber, columnNumber, source)); | 1232 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), |
| 1233 source)); |
1235 } | 1234 } |
1236 | 1235 |
1237 void V8DebuggerAgentImpl::reset() { | 1236 void V8DebuggerAgentImpl::reset() { |
1238 if (!enabled()) return; | 1237 if (!enabled()) return; |
1239 m_scheduledDebuggerStep = NoStep; | 1238 m_scheduledDebuggerStep = NoStep; |
1240 m_scripts.clear(); | 1239 m_scripts.clear(); |
1241 m_blackboxedPositions.clear(); | 1240 m_blackboxedPositions.clear(); |
1242 m_breakpointIdToDebuggerBreakpointIds.clear(); | 1241 m_breakpointIdToDebuggerBreakpointIds.clear(); |
1243 } | 1242 } |
1244 | 1243 |
1245 } // namespace v8_inspector | 1244 } // namespace v8_inspector |
OLD | NEW |