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 return String16::concat(scriptId, ':', lineNumber, ':', columnNumber, | 79 return String16::concat(breakpoint.script_id, ':', breakpoint.line_number, |
kozy
2016/11/15 23:29:47
Let's introduce id method on ScriptBreakpoint.
Clemens Hammacher
2016/11/16 12:06:24
Doing that would require ScriptBreakpoint to becom
| |
80 ':', breakpoint.column_number, | |
80 breakpointIdSuffix(source)); | 81 breakpointIdSuffix(source)); |
81 } | 82 } |
82 | 83 |
83 static bool positionComparator(const std::pair<int, int>& a, | 84 static bool positionComparator(const std::pair<int, int>& a, |
84 const std::pair<int, int>& b) { | 85 const std::pair<int, int>& b) { |
85 if (a.first != b.first) return a.first < b.first; | 86 if (a.first != b.first) return a.first < b.first; |
86 return a.second < b.second; | 87 return a.second < b.second; |
87 } | 88 } |
88 | 89 |
89 static std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation( | 90 static std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation( |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, | 279 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, |
279 std::move(newValue)); | 280 std::move(newValue)); |
280 } | 281 } |
281 if (breakpointsCookie->get(breakpointId)) | 282 if (breakpointsCookie->get(breakpointId)) |
282 return Response::Error("Breakpoint at specified location already exists."); | 283 return Response::Error("Breakpoint at specified location already exists."); |
283 | 284 |
284 breakpointsCookie->setObject( | 285 breakpointsCookie->setObject( |
285 breakpointId, buildObjectForBreakpointCookie( | 286 breakpointId, buildObjectForBreakpointCookie( |
286 url, lineNumber, columnNumber, condition, isRegex)); | 287 url, lineNumber, columnNumber, condition, isRegex)); |
287 | 288 |
288 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 289 ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition); |
289 for (const auto& script : m_scripts) { | 290 for (const auto& script : m_scripts) { |
290 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) | 291 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) |
291 continue; | 292 continue; |
292 std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( | 293 breakpoint.script_id = script.first; |
293 breakpointId, script.first, breakpoint, UserBreakpointSource); | 294 std::unique_ptr<protocol::Debugger::Location> location = |
295 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); | |
294 if (location) (*locations)->addItem(std::move(location)); | 296 if (location) (*locations)->addItem(std::move(location)); |
295 } | 297 } |
296 | 298 |
297 *outBreakpointId = breakpointId; | 299 *outBreakpointId = breakpointId; |
298 return Response::OK(); | 300 return Response::OK(); |
299 } | 301 } |
300 | 302 |
301 Response V8DebuggerAgentImpl::setBreakpoint( | 303 Response V8DebuggerAgentImpl::setBreakpoint( |
302 std::unique_ptr<protocol::Debugger::Location> location, | 304 std::unique_ptr<protocol::Debugger::Location> location, |
303 Maybe<String16> optionalCondition, String16* outBreakpointId, | 305 Maybe<String16> optionalCondition, String16* outBreakpointId, |
304 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { | 306 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { |
305 String16 scriptId = location->getScriptId(); | 307 ScriptBreakpoint breakpoint( |
306 int lineNumber = location->getLineNumber(); | 308 location->getScriptId(), location->getLineNumber(), |
307 int columnNumber = location->getColumnNumber(0); | 309 location->getColumnNumber(0), optionalCondition.fromMaybe(String16())); |
308 | 310 |
309 String16 condition = optionalCondition.fromMaybe(""); | 311 String16 breakpointId = |
310 | 312 generateBreakpointId(breakpoint, UserBreakpointSource); |
311 String16 breakpointId = generateBreakpointId( | |
312 scriptId, lineNumber, columnNumber, UserBreakpointSource); | |
313 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != | 313 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != |
314 m_breakpointIdToDebuggerBreakpointIds.end()) { | 314 m_breakpointIdToDebuggerBreakpointIds.end()) { |
315 return Response::Error("Breakpoint at specified location already exists."); | 315 return Response::Error("Breakpoint at specified location already exists."); |
316 } | 316 } |
317 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 317 *actualLocation = |
318 *actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, | 318 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); |
319 UserBreakpointSource); | |
320 if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); | 319 if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); |
321 *outBreakpointId = breakpointId; | 320 *outBreakpointId = breakpointId; |
322 return Response::OK(); | 321 return Response::OK(); |
323 } | 322 } |
324 | 323 |
325 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { | 324 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { |
326 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 325 if (!enabled()) return Response::Error(kDebuggerNotEnabled); |
327 protocol::DictionaryValue* breakpointsCookie = | 326 protocol::DictionaryValue* breakpointsCookie = |
328 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); | 327 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); |
329 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); | 328 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 } | 391 } |
393 | 392 |
394 Response V8DebuggerAgentImpl::continueToLocation( | 393 Response V8DebuggerAgentImpl::continueToLocation( |
395 std::unique_ptr<protocol::Debugger::Location> location) { | 394 std::unique_ptr<protocol::Debugger::Location> location) { |
396 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 395 if (!enabled()) return Response::Error(kDebuggerNotEnabled); |
397 if (!m_continueToLocationBreakpointId.isEmpty()) { | 396 if (!m_continueToLocationBreakpointId.isEmpty()) { |
398 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); | 397 m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); |
399 m_continueToLocationBreakpointId = ""; | 398 m_continueToLocationBreakpointId = ""; |
400 } | 399 } |
401 | 400 |
402 String16 scriptId = location->getScriptId(); | 401 ScriptBreakpoint breakpoint(location->getScriptId(), |
403 int lineNumber = location->getLineNumber(); | 402 location->getLineNumber(), |
404 int columnNumber = location->getColumnNumber(0); | 403 location->getColumnNumber(0), String16()); |
405 | 404 |
406 ScriptBreakpoint breakpoint(lineNumber, columnNumber, ""); | 405 m_continueToLocationBreakpointId = |
407 m_continueToLocationBreakpointId = m_debugger->setBreakpoint( | 406 m_debugger->setBreakpoint(breakpoint, nullptr, nullptr); |
408 scriptId, breakpoint, &lineNumber, &columnNumber); | |
409 return resume(); | 407 return resume(); |
410 } | 408 } |
411 | 409 |
412 bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { | 410 bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { |
413 DCHECK(enabled()); | 411 DCHECK(enabled()); |
414 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(); | 412 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(); |
415 for (size_t index = 0; index < callFrames.size(); ++index) { | 413 for (size_t index = 0; index < callFrames.size(); ++index) { |
416 if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) | 414 if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) |
417 return false; | 415 return false; |
418 } | 416 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut; | 478 if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut; |
481 | 479 |
482 if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1; | 480 if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1; |
483 | 481 |
484 ++m_skippedStepFrameCount; | 482 ++m_skippedStepFrameCount; |
485 return RequestStepFrame; | 483 return RequestStepFrame; |
486 } | 484 } |
487 | 485 |
488 std::unique_ptr<protocol::Debugger::Location> | 486 std::unique_ptr<protocol::Debugger::Location> |
489 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, | 487 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, |
490 const String16& scriptId, | |
491 const ScriptBreakpoint& breakpoint, | 488 const ScriptBreakpoint& breakpoint, |
492 BreakpointSource source) { | 489 BreakpointSource source) { |
493 DCHECK(enabled()); | 490 DCHECK(enabled()); |
494 // FIXME: remove these checks once crbug.com/520702 is resolved. | 491 // FIXME: remove these checks once crbug.com/520702 is resolved. |
495 CHECK(!breakpointId.isEmpty()); | 492 CHECK(!breakpointId.isEmpty()); |
496 CHECK(!scriptId.isEmpty()); | 493 CHECK(!breakpoint.script_id.isEmpty()); |
497 ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); | 494 ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id); |
498 if (scriptIterator == m_scripts.end()) return nullptr; | 495 if (scriptIterator == m_scripts.end()) return nullptr; |
499 if (breakpoint.lineNumber < scriptIterator->second->startLine() || | 496 if (breakpoint.line_number < scriptIterator->second->startLine() || |
500 scriptIterator->second->endLine() < breakpoint.lineNumber) | 497 scriptIterator->second->endLine() < breakpoint.line_number) |
501 return nullptr; | 498 return nullptr; |
502 | 499 |
503 int actualLineNumber; | 500 int actualLineNumber; |
504 int actualColumnNumber; | 501 int actualColumnNumber; |
505 String16 debuggerBreakpointId = m_debugger->setBreakpoint( | 502 String16 debuggerBreakpointId = m_debugger->setBreakpoint( |
506 scriptId, breakpoint, &actualLineNumber, &actualColumnNumber); | 503 breakpoint, &actualLineNumber, &actualColumnNumber); |
507 if (debuggerBreakpointId.isEmpty()) return nullptr; | 504 if (debuggerBreakpointId.isEmpty()) return nullptr; |
508 | 505 |
509 m_serverBreakpoints[debuggerBreakpointId] = | 506 m_serverBreakpoints[debuggerBreakpointId] = |
510 std::make_pair(breakpointId, source); | 507 std::make_pair(breakpointId, source); |
511 CHECK(!breakpointId.isEmpty()); | 508 CHECK(!breakpointId.isEmpty()); |
512 | 509 |
513 m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back( | 510 m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back( |
514 debuggerBreakpointId); | 511 debuggerBreakpointId); |
515 return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber); | 512 return buildProtocolLocation(breakpoint.script_id, actualLineNumber, |
513 actualColumnNumber); | |
516 } | 514 } |
517 | 515 |
518 Response V8DebuggerAgentImpl::searchInContent( | 516 Response V8DebuggerAgentImpl::searchInContent( |
519 const String16& scriptId, const String16& query, | 517 const String16& scriptId, const String16& query, |
520 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, | 518 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, |
521 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { | 519 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { |
522 v8::HandleScope handles(m_isolate); | 520 v8::HandleScope handles(m_isolate); |
523 ScriptsMap::iterator it = m_scripts.find(scriptId); | 521 ScriptsMap::iterator it = m_scripts.find(scriptId); |
524 if (it == m_scripts.end()) | 522 if (it == m_scripts.end()) |
525 return Response::Error("No script for id: " + scriptId); | 523 return Response::Error("No script for id: " + scriptId); |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { | 1054 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { |
1057 auto cookie = breakpointsCookie->at(i); | 1055 auto cookie = breakpointsCookie->at(i); |
1058 protocol::DictionaryValue* breakpointObject = | 1056 protocol::DictionaryValue* breakpointObject = |
1059 protocol::DictionaryValue::cast(cookie.second); | 1057 protocol::DictionaryValue::cast(cookie.second); |
1060 bool isRegex; | 1058 bool isRegex; |
1061 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); | 1059 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); |
1062 String16 url; | 1060 String16 url; |
1063 breakpointObject->getString(DebuggerAgentState::url, &url); | 1061 breakpointObject->getString(DebuggerAgentState::url, &url); |
1064 if (!matches(m_inspector, scriptURL, url, isRegex)) continue; | 1062 if (!matches(m_inspector, scriptURL, url, isRegex)) continue; |
1065 ScriptBreakpoint breakpoint; | 1063 ScriptBreakpoint breakpoint; |
1064 breakpoint.script_id = scriptId; | |
1066 breakpointObject->getInteger(DebuggerAgentState::lineNumber, | 1065 breakpointObject->getInteger(DebuggerAgentState::lineNumber, |
1067 &breakpoint.lineNumber); | 1066 &breakpoint.line_number); |
1068 breakpointObject->getInteger(DebuggerAgentState::columnNumber, | 1067 breakpointObject->getInteger(DebuggerAgentState::columnNumber, |
1069 &breakpoint.columnNumber); | 1068 &breakpoint.column_number); |
1070 breakpointObject->getString(DebuggerAgentState::condition, | 1069 breakpointObject->getString(DebuggerAgentState::condition, |
1071 &breakpoint.condition); | 1070 &breakpoint.condition); |
1072 std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( | 1071 std::unique_ptr<protocol::Debugger::Location> location = |
1073 cookie.first, scriptId, breakpoint, UserBreakpointSource); | 1072 resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource); |
1074 if (location) | 1073 if (location) |
1075 m_frontend.breakpointResolved(cookie.first, std::move(location)); | 1074 m_frontend.breakpointResolved(cookie.first, std::move(location)); |
1076 } | 1075 } |
1077 } | 1076 } |
1078 | 1077 |
1079 V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause( | 1078 V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause( |
1080 v8::Local<v8::Context> context, v8::Local<v8::Value> exception, | 1079 v8::Local<v8::Context> context, v8::Local<v8::Value> exception, |
1081 const std::vector<String16>& hitBreakpoints, bool isPromiseRejection, | 1080 const std::vector<String16>& hitBreakpoints, bool isPromiseRejection, |
1082 bool isUncaught) { | 1081 bool isUncaught) { |
1083 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1); | 1082 JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1202 | 1201 |
1203 void V8DebuggerAgentImpl::clearBreakDetails() { | 1202 void V8DebuggerAgentImpl::clearBreakDetails() { |
1204 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other; | 1203 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other; |
1205 m_breakAuxData = nullptr; | 1204 m_breakAuxData = nullptr; |
1206 } | 1205 } |
1207 | 1206 |
1208 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, | 1207 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, |
1209 int lineNumber, int columnNumber, | 1208 int lineNumber, int columnNumber, |
1210 BreakpointSource source, | 1209 BreakpointSource source, |
1211 const String16& condition) { | 1210 const String16& condition) { |
1212 String16 breakpointId = | 1211 ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition); |
1213 generateBreakpointId(scriptId, lineNumber, columnNumber, source); | 1212 String16 breakpointId = generateBreakpointId(breakpoint, source); |
1214 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 1213 resolveBreakpoint(breakpointId, breakpoint, source); |
1215 resolveBreakpoint(breakpointId, scriptId, breakpoint, source); | |
1216 } | 1214 } |
1217 | 1215 |
1218 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, | 1216 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, |
1219 int lineNumber, int columnNumber, | 1217 int lineNumber, int columnNumber, |
1220 BreakpointSource source) { | 1218 BreakpointSource source) { |
1221 removeBreakpointImpl( | 1219 removeBreakpointImpl(generateBreakpointId( |
1222 generateBreakpointId(scriptId, lineNumber, columnNumber, source)); | 1220 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), |
1221 source)); | |
1223 } | 1222 } |
1224 | 1223 |
1225 void V8DebuggerAgentImpl::reset() { | 1224 void V8DebuggerAgentImpl::reset() { |
1226 if (!enabled()) return; | 1225 if (!enabled()) return; |
1227 m_scheduledDebuggerStep = NoStep; | 1226 m_scheduledDebuggerStep = NoStep; |
1228 m_scripts.clear(); | 1227 m_scripts.clear(); |
1229 m_blackboxedPositions.clear(); | 1228 m_blackboxedPositions.clear(); |
1230 m_breakpointIdToDebuggerBreakpointIds.clear(); | 1229 m_breakpointIdToDebuggerBreakpointIds.clear(); |
1231 } | 1230 } |
1232 | 1231 |
1233 } // namespace v8_inspector | 1232 } // namespace v8_inspector |
OLD | NEW |