 Chromium Code Reviews
 Chromium Code Reviews Issue 2671193002:
  [inspector] restore provisional breakpoints smarter  (Closed)
    
  
    Issue 2671193002:
  [inspector] restore provisional breakpoints smarter  (Closed) 
  | 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 25 matching lines...) Expand all Loading... | |
| 36 using protocol::Runtime::ScriptId; | 36 using protocol::Runtime::ScriptId; | 
| 37 using protocol::Runtime::StackTrace; | 37 using protocol::Runtime::StackTrace; | 
| 38 using protocol::Runtime::RemoteObject; | 38 using protocol::Runtime::RemoteObject; | 
| 39 | 39 | 
| 40 namespace DebuggerAgentState { | 40 namespace DebuggerAgentState { | 
| 41 static const char javaScriptBreakpoints[] = "javaScriptBreakopints"; | 41 static const char javaScriptBreakpoints[] = "javaScriptBreakopints"; | 
| 42 static const char pauseOnExceptionsState[] = "pauseOnExceptionsState"; | 42 static const char pauseOnExceptionsState[] = "pauseOnExceptionsState"; | 
| 43 static const char asyncCallStackDepth[] = "asyncCallStackDepth"; | 43 static const char asyncCallStackDepth[] = "asyncCallStackDepth"; | 
| 44 static const char blackboxPattern[] = "blackboxPattern"; | 44 static const char blackboxPattern[] = "blackboxPattern"; | 
| 45 static const char debuggerEnabled[] = "debuggerEnabled"; | 45 static const char debuggerEnabled[] = "debuggerEnabled"; | 
| 46 static const char skipAllPauses[] = "skipAllPauses"; | |
| 46 | 47 | 
| 47 // Breakpoint properties. | 48 // Breakpoint properties. | 
| 48 static const char url[] = "url"; | 49 static const char url[] = "url"; | 
| 49 static const char isRegex[] = "isRegex"; | 50 static const char isRegex[] = "isRegex"; | 
| 50 static const char lineNumber[] = "lineNumber"; | 51 static const char lineNumber[] = "lineNumber"; | 
| 51 static const char columnNumber[] = "columnNumber"; | 52 static const char columnNumber[] = "columnNumber"; | 
| 52 static const char condition[] = "condition"; | 53 static const char condition[] = "condition"; | 
| 53 static const char skipAllPauses[] = "skipAllPauses"; | 54 static const char hint[] = "hint"; | 
| 54 | 55 | 
| 55 } // namespace DebuggerAgentState | 56 } // namespace DebuggerAgentState | 
| 56 | 57 | 
| 57 static const char kBacktraceObjectGroup[] = "backtrace"; | 58 static const char kBacktraceObjectGroup[] = "backtrace"; | 
| 58 static const char kDebuggerNotEnabled[] = "Debugger agent is not enabled"; | 59 static const char kDebuggerNotEnabled[] = "Debugger agent is not enabled"; | 
| 59 static const char kDebuggerNotPaused[] = | 60 static const char kDebuggerNotPaused[] = | 
| 60 "Can only perform operation while paused."; | 61 "Can only perform operation while paused."; | 
| 61 | 62 | 
| 63 static const size_t kBreakpointHintMaxLength = 128; | |
| 64 static const size_t kBreakpointHintMaxSearchOffset = 80 * 10; | |
| 65 | |
| 62 namespace { | 66 namespace { | 
| 63 | 67 | 
| 64 void TranslateWasmStackTraceLocations(Array<CallFrame>* stackTrace, | 68 void TranslateWasmStackTraceLocations(Array<CallFrame>* stackTrace, | 
| 65 WasmTranslation* wasmTranslation) { | 69 WasmTranslation* wasmTranslation) { | 
| 66 for (size_t i = 0, e = stackTrace->length(); i != e; ++i) { | 70 for (size_t i = 0, e = stackTrace->length(); i != e; ++i) { | 
| 67 protocol::Debugger::Location* location = stackTrace->get(i)->getLocation(); | 71 protocol::Debugger::Location* location = stackTrace->get(i)->getLocation(); | 
| 68 String16 scriptId = location->getScriptId(); | 72 String16 scriptId = location->getScriptId(); | 
| 69 int lineNumber = location->getLineNumber(); | 73 int lineNumber = location->getLineNumber(); | 
| 70 int columnNumber = location->getColumnNumber(-1); | 74 int columnNumber = location->getColumnNumber(-1); | 
| 71 | 75 | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 | 116 | 
| 113 std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation( | 117 std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation( | 
| 114 const String16& scriptId, int lineNumber, int columnNumber) { | 118 const String16& scriptId, int lineNumber, int columnNumber) { | 
| 115 return protocol::Debugger::Location::create() | 119 return protocol::Debugger::Location::create() | 
| 116 .setScriptId(scriptId) | 120 .setScriptId(scriptId) | 
| 117 .setLineNumber(lineNumber) | 121 .setLineNumber(lineNumber) | 
| 118 .setColumnNumber(columnNumber) | 122 .setColumnNumber(columnNumber) | 
| 119 .build(); | 123 .build(); | 
| 120 } | 124 } | 
| 121 | 125 | 
| 126 String16 breakpointHint(const V8DebuggerScript& script, | |
| 127 const ScriptBreakpoint& breakpoint) { | |
| 128 int offset = script.offset(breakpoint.line_number, breakpoint.column_number); | |
| 129 if (offset == V8DebuggerScript::kNoOffset) return String16(); | |
| 130 const String16& source = script.source(); | |
| 131 String16 hint = source.substring(offset, offset + kBreakpointHintMaxLength) | |
| 
alph
2017/02/27 22:01:29
the second arg of substring is length
 
kozy
2017/02/27 23:16:35
ooops, fixed.
 | |
| 132 .stripWhiteSpace(); | |
| 133 for (size_t i = 0; i < hint.length(); ++i) { | |
| 134 if (hint[i] == '\r' || hint[i] == '\n' || hint[i] == ';') { | |
| 135 return hint.substring(0, i); | |
| 136 } | |
| 137 } | |
| 138 return hint; | |
| 139 } | |
| 140 | |
| 141 void adjustBreakpointLocation(const V8DebuggerScript& script, | |
| 142 const String16& hint, | |
| 143 ScriptBreakpoint* breakpoint) { | |
| 144 if (hint.isEmpty()) return; | |
| 145 size_t offset = static_cast<size_t>( | |
| 146 script.offset(breakpoint->line_number, breakpoint->column_number)); | |
| 147 if (offset == static_cast<size_t>(V8DebuggerScript::kNoOffset)) return; | |
| 148 size_t searchAreaOffset = 0; | |
| 149 if (offset > kBreakpointHintMaxSearchOffset) | |
| 150 searchAreaOffset = offset - kBreakpointHintMaxSearchOffset; | |
| 151 String16 searchArea = | |
| 152 script.source() | |
| 153 .substring(searchAreaOffset, offset + kBreakpointHintMaxSearchOffset) | |
| 
alph
2017/02/27 22:01:29
The second arg of substring is length.
Also you ma
 
kozy
2017/02/27 23:16:35
Done.
 | |
| 154 .stripWhiteSpace(); | |
| 
alph
2017/02/27 22:01:29
As long as it strips whitespaces from the beginnin
 
kozy
2017/02/27 23:16:35
Done.
 | |
| 155 size_t hintOffset = searchArea.find(hint); | |
| 156 if (hintOffset == String16::kNotFound) return; | |
| 157 size_t bestMatch = hintOffset + searchAreaOffset; | |
| 158 size_t bestDistance = | |
| 159 bestMatch > offset ? bestMatch - offset : offset - bestMatch; | |
| 
alph
2017/02/27 22:01:29
I wonder if you can use intptr_t instead of size_t
 
kozy
2017/02/27 23:16:35
Done.
 | |
| 160 while (hintOffset != String16::kNotFound) { | |
| 
alph
2017/02/27 22:01:29
the condition always holds
 
kozy
2017/02/27 23:16:35
Done.
 | |
| 161 hintOffset = searchArea.find(hint, hintOffset + 1); | |
| 162 if (hintOffset == String16::kNotFound) break; | |
| 163 size_t hintDistance = hintOffset + searchAreaOffset > offset | |
| 
alph
2017/02/27 22:01:29
You don't need to do it in a loop. Just two checks
 
kozy
2017/02/27 23:16:35
Done.
 | |
| 164 ? hintOffset + searchAreaOffset - offset | |
| 165 : offset - (hintOffset + searchAreaOffset); | |
| 166 if (hintDistance < bestDistance) { | |
| 167 bestMatch = hintOffset + searchAreaOffset; | |
| 168 bestDistance = hintDistance; | |
| 169 } else { | |
| 170 break; | |
| 171 } | |
| 172 } | |
| 173 if (bestMatch == String16::kNotFound) return; | |
| 
alph
2017/02/27 22:01:29
always false
 
kozy
2017/02/27 23:16:35
Done.
 | |
| 174 v8::debug::Location hintPosition = script.location(bestMatch); | |
| 175 if (hintPosition.IsEmpty()) return; | |
| 176 breakpoint->line_number = hintPosition.GetLineNumber(); | |
| 177 breakpoint->column_number = hintPosition.GetColumnNumber(); | |
| 178 } | |
| 122 } // namespace | 179 } // namespace | 
| 123 | 180 | 
| 124 V8DebuggerAgentImpl::V8DebuggerAgentImpl( | 181 V8DebuggerAgentImpl::V8DebuggerAgentImpl( | 
| 125 V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, | 182 V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, | 
| 126 protocol::DictionaryValue* state) | 183 protocol::DictionaryValue* state) | 
| 127 : m_inspector(session->inspector()), | 184 : m_inspector(session->inspector()), | 
| 128 m_debugger(m_inspector->debugger()), | 185 m_debugger(m_inspector->debugger()), | 
| 129 m_session(session), | 186 m_session(session), | 
| 130 m_enabled(false), | 187 m_enabled(false), | 
| 131 m_state(state), | 188 m_state(state), | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 | 289 | 
| 233 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { | 290 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { | 
| 234 m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip); | 291 m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip); | 
| 235 m_skipAllPauses = skip; | 292 m_skipAllPauses = skip; | 
| 236 return Response::OK(); | 293 return Response::OK(); | 
| 237 } | 294 } | 
| 238 | 295 | 
| 239 static std::unique_ptr<protocol::DictionaryValue> | 296 static std::unique_ptr<protocol::DictionaryValue> | 
| 240 buildObjectForBreakpointCookie(const String16& url, int lineNumber, | 297 buildObjectForBreakpointCookie(const String16& url, int lineNumber, | 
| 241 int columnNumber, const String16& condition, | 298 int columnNumber, const String16& condition, | 
| 242 bool isRegex) { | 299 bool isRegex, const String16& hint) { | 
| 243 std::unique_ptr<protocol::DictionaryValue> breakpointObject = | 300 std::unique_ptr<protocol::DictionaryValue> breakpointObject = | 
| 244 protocol::DictionaryValue::create(); | 301 protocol::DictionaryValue::create(); | 
| 245 breakpointObject->setString(DebuggerAgentState::url, url); | 302 breakpointObject->setString(DebuggerAgentState::url, url); | 
| 246 breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); | 303 breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); | 
| 247 breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); | 304 breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); | 
| 248 breakpointObject->setString(DebuggerAgentState::condition, condition); | 305 breakpointObject->setString(DebuggerAgentState::condition, condition); | 
| 249 breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex); | 306 breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex); | 
| 307 if (!hint.isEmpty()) { | |
| 308 breakpointObject->setString(DebuggerAgentState::hint, hint); | |
| 309 } | |
| 250 return breakpointObject; | 310 return breakpointObject; | 
| 251 } | 311 } | 
| 252 | 312 | 
| 253 static bool matches(V8InspectorImpl* inspector, const String16& url, | 313 static bool matches(V8InspectorImpl* inspector, const String16& url, | 
| 254 const String16& pattern, bool isRegex) { | 314 const String16& pattern, bool isRegex) { | 
| 255 if (isRegex) { | 315 if (isRegex) { | 
| 256 V8Regex regex(inspector, pattern, true); | 316 V8Regex regex(inspector, pattern, true); | 
| 257 return regex.match(url) != -1; | 317 return regex.match(url) != -1; | 
| 258 } | 318 } | 
| 259 return url == pattern; | 319 return url == pattern; | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 286 if (!breakpointsCookie) { | 346 if (!breakpointsCookie) { | 
| 287 std::unique_ptr<protocol::DictionaryValue> newValue = | 347 std::unique_ptr<protocol::DictionaryValue> newValue = | 
| 288 protocol::DictionaryValue::create(); | 348 protocol::DictionaryValue::create(); | 
| 289 breakpointsCookie = newValue.get(); | 349 breakpointsCookie = newValue.get(); | 
| 290 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, | 350 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, | 
| 291 std::move(newValue)); | 351 std::move(newValue)); | 
| 292 } | 352 } | 
| 293 if (breakpointsCookie->get(breakpointId)) | 353 if (breakpointsCookie->get(breakpointId)) | 
| 294 return Response::Error("Breakpoint at specified location already exists."); | 354 return Response::Error("Breakpoint at specified location already exists."); | 
| 295 | 355 | 
| 296 breakpointsCookie->setObject( | 356 String16 hint; | 
| 297 breakpointId, buildObjectForBreakpointCookie( | |
| 298 url, lineNumber, columnNumber, condition, isRegex)); | |
| 299 | |
| 300 ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition); | 357 ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition); | 
| 301 for (const auto& script : m_scripts) { | 358 for (const auto& script : m_scripts) { | 
| 302 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) | 359 if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) | 
| 303 continue; | 360 continue; | 
| 304 breakpoint.script_id = script.first; | 361 breakpoint.script_id = script.first; | 
| 305 std::unique_ptr<protocol::Debugger::Location> location = | 362 std::unique_ptr<protocol::Debugger::Location> location = | 
| 306 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); | 363 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource, hint); | 
| 364 if (!isRegex) hint = breakpointHint(*script.second, breakpoint); | |
| 307 if (location) (*locations)->addItem(std::move(location)); | 365 if (location) (*locations)->addItem(std::move(location)); | 
| 308 } | 366 } | 
| 309 | 367 | 
| 368 breakpointsCookie->setObject( | |
| 369 breakpointId, | |
| 370 buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, | |
| 371 isRegex, hint)); | |
| 372 | |
| 310 *outBreakpointId = breakpointId; | 373 *outBreakpointId = breakpointId; | 
| 311 return Response::OK(); | 374 return Response::OK(); | 
| 312 } | 375 } | 
| 313 | 376 | 
| 314 Response V8DebuggerAgentImpl::setBreakpoint( | 377 Response V8DebuggerAgentImpl::setBreakpoint( | 
| 315 std::unique_ptr<protocol::Debugger::Location> location, | 378 std::unique_ptr<protocol::Debugger::Location> location, | 
| 316 Maybe<String16> optionalCondition, String16* outBreakpointId, | 379 Maybe<String16> optionalCondition, String16* outBreakpointId, | 
| 317 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { | 380 std::unique_ptr<protocol::Debugger::Location>* actualLocation) { | 
| 318 ScriptBreakpoint breakpoint( | 381 ScriptBreakpoint breakpoint( | 
| 319 location->getScriptId(), location->getLineNumber(), | 382 location->getScriptId(), location->getLineNumber(), | 
| 320 location->getColumnNumber(0), optionalCondition.fromMaybe(String16())); | 383 location->getColumnNumber(0), optionalCondition.fromMaybe(String16())); | 
| 321 | 384 | 
| 322 String16 breakpointId = | 385 String16 breakpointId = | 
| 323 generateBreakpointId(breakpoint, UserBreakpointSource); | 386 generateBreakpointId(breakpoint, UserBreakpointSource); | 
| 324 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != | 387 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != | 
| 325 m_breakpointIdToDebuggerBreakpointIds.end()) { | 388 m_breakpointIdToDebuggerBreakpointIds.end()) { | 
| 326 return Response::Error("Breakpoint at specified location already exists."); | 389 return Response::Error("Breakpoint at specified location already exists."); | 
| 327 } | 390 } | 
| 328 *actualLocation = | 391 *actualLocation = resolveBreakpoint( | 
| 329 resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); | 392 breakpointId, breakpoint, UserBreakpointSource, /* hint */ String16()); | 
| 330 if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); | 393 if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); | 
| 331 *outBreakpointId = breakpointId; | 394 *outBreakpointId = breakpointId; | 
| 332 return Response::OK(); | 395 return Response::OK(); | 
| 333 } | 396 } | 
| 334 | 397 | 
| 335 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { | 398 Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { | 
| 336 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 399 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 
| 337 protocol::DictionaryValue* breakpointsCookie = | 400 protocol::DictionaryValue* breakpointsCookie = | 
| 338 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); | 401 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); | 
| 339 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); | 402 if (breakpointsCookie) breakpointsCookie->remove(breakpointId); | 
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 // Ranges array contains positions in script where blackbox state is changed. | 513 // Ranges array contains positions in script where blackbox state is changed. | 
| 451 // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is | 514 // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is | 
| 452 // blackboxed... | 515 // blackboxed... | 
| 453 return itStartRange == itEndRange && | 516 return itStartRange == itEndRange && | 
| 454 std::distance(ranges.begin(), itStartRange) % 2; | 517 std::distance(ranges.begin(), itStartRange) % 2; | 
| 455 } | 518 } | 
| 456 | 519 | 
| 457 std::unique_ptr<protocol::Debugger::Location> | 520 std::unique_ptr<protocol::Debugger::Location> | 
| 458 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, | 521 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, | 
| 459 const ScriptBreakpoint& breakpoint, | 522 const ScriptBreakpoint& breakpoint, | 
| 460 BreakpointSource source) { | 523 BreakpointSource source, | 
| 524 const String16& hint) { | |
| 461 v8::HandleScope handles(m_isolate); | 525 v8::HandleScope handles(m_isolate); | 
| 462 DCHECK(enabled()); | 526 DCHECK(enabled()); | 
| 463 // FIXME: remove these checks once crbug.com/520702 is resolved. | 527 // FIXME: remove these checks once crbug.com/520702 is resolved. | 
| 464 CHECK(!breakpointId.isEmpty()); | 528 CHECK(!breakpointId.isEmpty()); | 
| 465 CHECK(!breakpoint.script_id.isEmpty()); | 529 CHECK(!breakpoint.script_id.isEmpty()); | 
| 466 ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id); | 530 ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id); | 
| 467 if (scriptIterator == m_scripts.end()) return nullptr; | 531 if (scriptIterator == m_scripts.end()) return nullptr; | 
| 468 if (breakpoint.line_number < scriptIterator->second->startLine() || | 532 if (breakpoint.line_number < scriptIterator->second->startLine() || | 
| 469 scriptIterator->second->endLine() < breakpoint.line_number) | 533 scriptIterator->second->endLine() < breakpoint.line_number) | 
| 470 return nullptr; | 534 return nullptr; | 
| 471 | 535 | 
| 472 // Translate from protocol location to v8 location for the debugger. | 536 // Translate from protocol location to v8 location for the debugger. | 
| 473 ScriptBreakpoint translatedBreakpoint = breakpoint; | 537 ScriptBreakpoint translatedBreakpoint = breakpoint; | 
| 538 adjustBreakpointLocation(*scriptIterator->second, hint, | |
| 539 &translatedBreakpoint); | |
| 474 m_debugger->wasmTranslation()->TranslateProtocolLocationToWasmScriptLocation( | 540 m_debugger->wasmTranslation()->TranslateProtocolLocationToWasmScriptLocation( | 
| 475 &translatedBreakpoint.script_id, &translatedBreakpoint.line_number, | 541 &translatedBreakpoint.script_id, &translatedBreakpoint.line_number, | 
| 476 &translatedBreakpoint.column_number); | 542 &translatedBreakpoint.column_number); | 
| 477 | 543 | 
| 478 int actualLineNumber; | 544 int actualLineNumber; | 
| 479 int actualColumnNumber; | 545 int actualColumnNumber; | 
| 480 String16 debuggerBreakpointId = m_debugger->setBreakpoint( | 546 String16 debuggerBreakpointId = m_debugger->setBreakpoint( | 
| 481 translatedBreakpoint, &actualLineNumber, &actualColumnNumber); | 547 translatedBreakpoint, &actualLineNumber, &actualColumnNumber); | 
| 482 if (debuggerBreakpointId.isEmpty()) return nullptr; | 548 if (debuggerBreakpointId.isEmpty()) return nullptr; | 
| 483 | 549 | 
| (...skipping 14 matching lines...) Expand all Loading... | |
| 498 Response V8DebuggerAgentImpl::searchInContent( | 564 Response V8DebuggerAgentImpl::searchInContent( | 
| 499 const String16& scriptId, const String16& query, | 565 const String16& scriptId, const String16& query, | 
| 500 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, | 566 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, | 
| 501 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { | 567 std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { | 
| 502 v8::HandleScope handles(m_isolate); | 568 v8::HandleScope handles(m_isolate); | 
| 503 ScriptsMap::iterator it = m_scripts.find(scriptId); | 569 ScriptsMap::iterator it = m_scripts.find(scriptId); | 
| 504 if (it == m_scripts.end()) | 570 if (it == m_scripts.end()) | 
| 505 return Response::Error("No script for id: " + scriptId); | 571 return Response::Error("No script for id: " + scriptId); | 
| 506 | 572 | 
| 507 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = | 573 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = | 
| 508 searchInTextByLinesImpl(m_session, it->second->source(m_isolate), query, | 574 searchInTextByLinesImpl(m_session, it->second->source(), query, | 
| 509 optionalCaseSensitive.fromMaybe(false), | 575 optionalCaseSensitive.fromMaybe(false), | 
| 510 optionalIsRegex.fromMaybe(false)); | 576 optionalIsRegex.fromMaybe(false)); | 
| 511 *results = protocol::Array<protocol::Debugger::SearchMatch>::create(); | 577 *results = protocol::Array<protocol::Debugger::SearchMatch>::create(); | 
| 512 for (size_t i = 0; i < matches.size(); ++i) | 578 for (size_t i = 0; i < matches.size(); ++i) | 
| 513 (*results)->addItem(std::move(matches[i])); | 579 (*results)->addItem(std::move(matches[i])); | 
| 514 return Response::OK(); | 580 return Response::OK(); | 
| 515 } | 581 } | 
| 516 | 582 | 
| 517 Response V8DebuggerAgentImpl::setScriptSource( | 583 Response V8DebuggerAgentImpl::setScriptSource( | 
| 518 const String16& scriptId, const String16& newContent, Maybe<bool> dryRun, | 584 const String16& scriptId, const String16& newContent, Maybe<bool> dryRun, | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 531 } | 597 } | 
| 532 | 598 | 
| 533 v8::HandleScope handles(m_isolate); | 599 v8::HandleScope handles(m_isolate); | 
| 534 v8::Local<v8::String> newSource = toV8String(m_isolate, newContent); | 600 v8::Local<v8::String> newSource = toV8String(m_isolate, newContent); | 
| 535 bool compileError = false; | 601 bool compileError = false; | 
| 536 Response response = m_debugger->setScriptSource( | 602 Response response = m_debugger->setScriptSource( | 
| 537 scriptId, newSource, dryRun.fromMaybe(false), optOutCompileError, | 603 scriptId, newSource, dryRun.fromMaybe(false), optOutCompileError, | 
| 538 &m_pausedCallFrames, stackChanged, &compileError); | 604 &m_pausedCallFrames, stackChanged, &compileError); | 
| 539 if (!response.isSuccess() || compileError) return response; | 605 if (!response.isSuccess() || compileError) return response; | 
| 540 | 606 | 
| 541 it->second->setSource(newSource); | 607 it->second->setSource(newContent); | 
| 542 std::unique_ptr<Array<CallFrame>> callFrames; | 608 std::unique_ptr<Array<CallFrame>> callFrames; | 
| 543 response = currentCallFrames(&callFrames); | 609 response = currentCallFrames(&callFrames); | 
| 544 if (!response.isSuccess()) return response; | 610 if (!response.isSuccess()) return response; | 
| 545 *newCallFrames = std::move(callFrames); | 611 *newCallFrames = std::move(callFrames); | 
| 546 *asyncStackTrace = currentAsyncStackTrace(); | 612 *asyncStackTrace = currentAsyncStackTrace(); | 
| 547 return Response::OK(); | 613 return Response::OK(); | 
| 548 } | 614 } | 
| 549 | 615 | 
| 550 Response V8DebuggerAgentImpl::restartFrame( | 616 Response V8DebuggerAgentImpl::restartFrame( | 
| 551 const String16& callFrameId, | 617 const String16& callFrameId, | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 576 *asyncStackTrace = currentAsyncStackTrace(); | 642 *asyncStackTrace = currentAsyncStackTrace(); | 
| 577 return Response::OK(); | 643 return Response::OK(); | 
| 578 } | 644 } | 
| 579 | 645 | 
| 580 Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId, | 646 Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId, | 
| 581 String16* scriptSource) { | 647 String16* scriptSource) { | 
| 582 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 648 if (!enabled()) return Response::Error(kDebuggerNotEnabled); | 
| 583 ScriptsMap::iterator it = m_scripts.find(scriptId); | 649 ScriptsMap::iterator it = m_scripts.find(scriptId); | 
| 584 if (it == m_scripts.end()) | 650 if (it == m_scripts.end()) | 
| 585 return Response::Error("No script for id: " + scriptId); | 651 return Response::Error("No script for id: " + scriptId); | 
| 586 v8::HandleScope handles(m_isolate); | 652 *scriptSource = it->second->source(); | 
| 587 *scriptSource = it->second->source(m_isolate); | |
| 588 return Response::OK(); | 653 return Response::OK(); | 
| 589 } | 654 } | 
| 590 | 655 | 
| 591 void V8DebuggerAgentImpl::pushBreakDetails( | 656 void V8DebuggerAgentImpl::pushBreakDetails( | 
| 592 const String16& breakReason, | 657 const String16& breakReason, | 
| 593 std::unique_ptr<protocol::DictionaryValue> breakAuxData) { | 658 std::unique_ptr<protocol::DictionaryValue> breakAuxData) { | 
| 594 m_breakReason.push_back(std::make_pair(breakReason, std::move(breakAuxData))); | 659 m_breakReason.push_back(std::make_pair(breakReason, std::move(breakAuxData))); | 
| 595 } | 660 } | 
| 596 | 661 | 
| 597 void V8DebuggerAgentImpl::popBreakDetails() { | 662 void V8DebuggerAgentImpl::popBreakDetails() { | 
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain(); | 1051 V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain(); | 
| 987 return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger) | 1052 return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger) | 
| 988 : nullptr; | 1053 : nullptr; | 
| 989 } | 1054 } | 
| 990 | 1055 | 
| 991 bool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPaused(); } | 1056 bool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPaused(); } | 
| 992 | 1057 | 
| 993 void V8DebuggerAgentImpl::didParseSource( | 1058 void V8DebuggerAgentImpl::didParseSource( | 
| 994 std::unique_ptr<V8DebuggerScript> script, bool success) { | 1059 std::unique_ptr<V8DebuggerScript> script, bool success) { | 
| 995 v8::HandleScope handles(m_isolate); | 1060 v8::HandleScope handles(m_isolate); | 
| 996 String16 scriptSource = script->source(m_isolate); | 1061 String16 scriptSource = script->source(); | 
| 997 if (!success) script->setSourceURL(findSourceURL(scriptSource, false)); | 1062 if (!success) script->setSourceURL(findSourceURL(scriptSource, false)); | 
| 998 if (!success) | 1063 if (!success) | 
| 999 script->setSourceMappingURL(findSourceMapURL(scriptSource, false)); | 1064 script->setSourceMappingURL(findSourceMapURL(scriptSource, false)); | 
| 1000 | 1065 | 
| 1001 int contextId = script->executionContextId(); | 1066 int contextId = script->executionContextId(); | 
| 1002 int contextGroupId = m_inspector->contextGroupId(contextId); | 1067 int contextGroupId = m_inspector->contextGroupId(contextId); | 
| 1003 InspectedContext* inspected = | 1068 InspectedContext* inspected = | 
| 1004 m_inspector->getContext(contextGroupId, contextId); | 1069 m_inspector->getContext(contextGroupId, contextId); | 
| 1005 std::unique_ptr<protocol::DictionaryValue> executionContextAuxData; | 1070 std::unique_ptr<protocol::DictionaryValue> executionContextAuxData; | 
| 1006 if (inspected) { | 1071 if (inspected) { | 
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1029 Maybe<String16> sourceMapURLParam = scriptRef->sourceMappingURL(); | 1094 Maybe<String16> sourceMapURLParam = scriptRef->sourceMappingURL(); | 
| 1030 Maybe<protocol::DictionaryValue> executionContextAuxDataParam( | 1095 Maybe<protocol::DictionaryValue> executionContextAuxDataParam( | 
| 1031 std::move(executionContextAuxData)); | 1096 std::move(executionContextAuxData)); | 
| 1032 const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; | 1097 const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; | 
| 1033 const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; | 1098 const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; | 
| 1034 const bool* isModuleParam = isModule ? &isModule : nullptr; | 1099 const bool* isModuleParam = isModule ? &isModule : nullptr; | 
| 1035 if (success) | 1100 if (success) | 
| 1036 m_frontend.scriptParsed( | 1101 m_frontend.scriptParsed( | 
| 1037 scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), | 1102 scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), | 
| 1038 scriptRef->endLine(), scriptRef->endColumn(), contextId, | 1103 scriptRef->endLine(), scriptRef->endColumn(), contextId, | 
| 1039 scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam), | 1104 scriptRef->hash(), std::move(executionContextAuxDataParam), | 
| 1040 isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam, | 1105 isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam, | 
| 1041 isModuleParam); | 1106 isModuleParam); | 
| 1042 else | 1107 else | 
| 1043 m_frontend.scriptFailedToParse( | 1108 m_frontend.scriptFailedToParse( | 
| 1044 scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), | 1109 scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), | 
| 1045 scriptRef->endLine(), scriptRef->endColumn(), contextId, | 1110 scriptRef->endLine(), scriptRef->endColumn(), contextId, | 
| 1046 scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam), | 1111 scriptRef->hash(), std::move(executionContextAuxDataParam), | 
| 1047 std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam); | 1112 std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam); | 
| 1048 | 1113 | 
| 1049 if (scriptURL.isEmpty() || !success) return; | 1114 if (scriptURL.isEmpty() || !success) return; | 
| 1050 | 1115 | 
| 1051 protocol::DictionaryValue* breakpointsCookie = | 1116 protocol::DictionaryValue* breakpointsCookie = | 
| 1052 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); | 1117 m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); | 
| 1053 if (!breakpointsCookie) return; | 1118 if (!breakpointsCookie) return; | 
| 1054 | 1119 | 
| 1055 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { | 1120 for (size_t i = 0; i < breakpointsCookie->size(); ++i) { | 
| 1056 auto cookie = breakpointsCookie->at(i); | 1121 auto cookie = breakpointsCookie->at(i); | 
| 1057 protocol::DictionaryValue* breakpointObject = | 1122 protocol::DictionaryValue* breakpointObject = | 
| 1058 protocol::DictionaryValue::cast(cookie.second); | 1123 protocol::DictionaryValue::cast(cookie.second); | 
| 1059 bool isRegex; | 1124 bool isRegex; | 
| 1060 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); | 1125 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); | 
| 1061 String16 url; | 1126 String16 url; | 
| 1062 breakpointObject->getString(DebuggerAgentState::url, &url); | 1127 breakpointObject->getString(DebuggerAgentState::url, &url); | 
| 1063 if (!matches(m_inspector, scriptURL, url, isRegex)) continue; | 1128 if (!matches(m_inspector, scriptURL, url, isRegex)) continue; | 
| 1064 ScriptBreakpoint breakpoint; | 1129 ScriptBreakpoint breakpoint; | 
| 1065 breakpoint.script_id = scriptId; | 1130 breakpoint.script_id = scriptId; | 
| 1066 breakpointObject->getInteger(DebuggerAgentState::lineNumber, | 1131 breakpointObject->getInteger(DebuggerAgentState::lineNumber, | 
| 1067 &breakpoint.line_number); | 1132 &breakpoint.line_number); | 
| 1068 breakpointObject->getInteger(DebuggerAgentState::columnNumber, | 1133 breakpointObject->getInteger(DebuggerAgentState::columnNumber, | 
| 1069 &breakpoint.column_number); | 1134 &breakpoint.column_number); | 
| 1070 breakpointObject->getString(DebuggerAgentState::condition, | 1135 breakpointObject->getString(DebuggerAgentState::condition, | 
| 1071 &breakpoint.condition); | 1136 &breakpoint.condition); | 
| 1137 String16 hint; | |
| 1138 bool hasHint = breakpointObject->getString(DebuggerAgentState::hint, &hint); | |
| 1072 std::unique_ptr<protocol::Debugger::Location> location = | 1139 std::unique_ptr<protocol::Debugger::Location> location = | 
| 1073 resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource); | 1140 resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource, hint); | 
| 1141 if (!hasHint) { | |
| 1142 hint = breakpointHint(*scriptRef, breakpoint); | |
| 1143 if (!hint.isEmpty()) | |
| 1144 breakpointObject->setString(DebuggerAgentState::hint, hint); | |
| 1145 } | |
| 1074 if (location) | 1146 if (location) | 
| 1075 m_frontend.breakpointResolved(cookie.first, std::move(location)); | 1147 m_frontend.breakpointResolved(cookie.first, std::move(location)); | 
| 1076 } | 1148 } | 
| 1077 } | 1149 } | 
| 1078 | 1150 | 
| 1079 void V8DebuggerAgentImpl::didPause(int contextId, | 1151 void V8DebuggerAgentImpl::didPause(int contextId, | 
| 1080 v8::Local<v8::Value> exception, | 1152 v8::Local<v8::Value> exception, | 
| 1081 const std::vector<String16>& hitBreakpoints, | 1153 const std::vector<String16>& hitBreakpoints, | 
| 1082 bool isPromiseRejection, bool isUncaught, | 1154 bool isPromiseRejection, bool isUncaught, | 
| 1083 bool isOOMBreak) { | 1155 bool isOOMBreak) { | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1202 return; | 1274 return; | 
| 1203 breakProgram(breakReason, std::move(data)); | 1275 breakProgram(breakReason, std::move(data)); | 
| 1204 } | 1276 } | 
| 1205 | 1277 | 
| 1206 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, | 1278 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, | 
| 1207 int lineNumber, int columnNumber, | 1279 int lineNumber, int columnNumber, | 
| 1208 BreakpointSource source, | 1280 BreakpointSource source, | 
| 1209 const String16& condition) { | 1281 const String16& condition) { | 
| 1210 ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition); | 1282 ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition); | 
| 1211 String16 breakpointId = generateBreakpointId(breakpoint, source); | 1283 String16 breakpointId = generateBreakpointId(breakpoint, source); | 
| 1212 resolveBreakpoint(breakpointId, breakpoint, source); | 1284 resolveBreakpoint(breakpointId, breakpoint, source, /* hint */ String16()); | 
| 1213 } | 1285 } | 
| 1214 | 1286 | 
| 1215 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, | 1287 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, | 
| 1216 int lineNumber, int columnNumber, | 1288 int lineNumber, int columnNumber, | 
| 1217 BreakpointSource source) { | 1289 BreakpointSource source) { | 
| 1218 removeBreakpointImpl(generateBreakpointId( | 1290 removeBreakpointImpl(generateBreakpointId( | 
| 1219 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), | 1291 ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), | 
| 1220 source)); | 1292 source)); | 
| 1221 } | 1293 } | 
| 1222 | 1294 | 
| 1223 void V8DebuggerAgentImpl::reset() { | 1295 void V8DebuggerAgentImpl::reset() { | 
| 1224 if (!enabled()) return; | 1296 if (!enabled()) return; | 
| 1225 m_scheduledDebuggerStep = NoStep; | 1297 m_scheduledDebuggerStep = NoStep; | 
| 1226 m_blackboxedPositions.clear(); | 1298 m_blackboxedPositions.clear(); | 
| 1227 resetBlackboxedStateCache(); | 1299 resetBlackboxedStateCache(); | 
| 1228 m_scripts.clear(); | 1300 m_scripts.clear(); | 
| 1229 m_breakpointIdToDebuggerBreakpointIds.clear(); | 1301 m_breakpointIdToDebuggerBreakpointIds.clear(); | 
| 1230 } | 1302 } | 
| 1231 | 1303 | 
| 1232 } // namespace v8_inspector | 1304 } // namespace v8_inspector | 
| OLD | NEW |