| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium 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 "platform/v8_inspector/V8DebuggerAgentImpl.h" | 5 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" |
| 6 | 6 |
| 7 #include "platform/JSONValues.h" | 7 #include "platform/JSONValues.h" |
| 8 #include "platform/v8_inspector/AsyncCallChain.h" | 8 #include "platform/v8_inspector/AsyncCallChain.h" |
| 9 #include "platform/v8_inspector/IgnoreExceptionsScope.h" | 9 #include "platform/v8_inspector/IgnoreExceptionsScope.h" |
| 10 #include "platform/v8_inspector/InjectedScript.h" | 10 #include "platform/v8_inspector/InjectedScript.h" |
| 11 #include "platform/v8_inspector/InjectedScriptHost.h" | 11 #include "platform/v8_inspector/InjectedScriptHost.h" |
| 12 #include "platform/v8_inspector/InjectedScriptManager.h" | 12 #include "platform/v8_inspector/InjectedScriptManager.h" |
| 13 #include "platform/v8_inspector/JavaScriptCallFrame.h" | 13 #include "platform/v8_inspector/JavaScriptCallFrame.h" |
| 14 #include "platform/v8_inspector/PromiseTracker.h" | 14 #include "platform/v8_inspector/PromiseTracker.h" |
| 15 #include "platform/v8_inspector/RemoteObjectId.h" | 15 #include "platform/v8_inspector/RemoteObjectId.h" |
| 16 #include "platform/v8_inspector/V8AsyncCallTracker.h" | 16 #include "platform/v8_inspector/V8AsyncCallTracker.h" |
| 17 #include "platform/v8_inspector/V8JavaScriptCallFrame.h" | 17 #include "platform/v8_inspector/V8JavaScriptCallFrame.h" |
| 18 #include "platform/v8_inspector/V8Regex.h" | 18 #include "platform/v8_inspector/V8Regex.h" |
| 19 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" | 19 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" |
| 20 #include "platform/v8_inspector/V8StackTraceImpl.h" | 20 #include "platform/v8_inspector/V8StackTraceImpl.h" |
| 21 #include "platform/v8_inspector/V8StringUtil.h" | 21 #include "platform/v8_inspector/V8StringUtil.h" |
| 22 #include "platform/v8_inspector/public/V8ContentSearchUtil.h" | 22 #include "platform/v8_inspector/public/V8ContentSearchUtil.h" |
| 23 #include "platform/v8_inspector/public/V8Debugger.h" | 23 #include "platform/v8_inspector/public/V8Debugger.h" |
| 24 #include "platform/v8_inspector/public/V8DebuggerClient.h" | 24 #include "platform/v8_inspector/public/V8DebuggerClient.h" |
| 25 #include "wtf/Optional.h" | 25 #include "wtf/Optional.h" |
| 26 #include "wtf/text/StringBuilder.h" | 26 #include "wtf/text/StringBuilder.h" |
| 27 #include "wtf/text/WTFString.h" | 27 #include "wtf/text/WTFString.h" |
| 28 | 28 |
| 29 using blink::protocol::TypeBuilder::Array; | 29 using blink::protocol::Array; |
| 30 using blink::protocol::TypeBuilder::Debugger::AsyncOperation; | 30 using blink::protocol::OptionalValue; |
| 31 using blink::protocol::TypeBuilder::Debugger::BreakpointId; | 31 using blink::protocol::Debugger::AsyncOperation; |
| 32 using blink::protocol::TypeBuilder::Debugger::CallFrame; | 32 using blink::protocol::Debugger::BreakpointId; |
| 33 using blink::protocol::TypeBuilder::Debugger::CollectionEntry; | 33 using blink::protocol::Debugger::CallFrame; |
| 34 using blink::protocol::TypeBuilder::Runtime::ExceptionDetails; | 34 using blink::protocol::Debugger::CollectionEntry; |
| 35 using blink::protocol::TypeBuilder::Debugger::FunctionDetails; | 35 using blink::protocol::Runtime::ExceptionDetails; |
| 36 using blink::protocol::TypeBuilder::Debugger::GeneratorObjectDetails; | 36 using blink::protocol::Debugger::FunctionDetails; |
| 37 using blink::protocol::TypeBuilder::Debugger::PromiseDetails; | 37 using blink::protocol::Debugger::GeneratorObjectDetails; |
| 38 using blink::protocol::TypeBuilder::Runtime::ScriptId; | 38 using blink::protocol::Debugger::PromiseDetails; |
| 39 using blink::protocol::TypeBuilder::Debugger::StackTrace; | 39 using blink::protocol::Runtime::ScriptId; |
| 40 using blink::protocol::TypeBuilder::Runtime::RemoteObject; | 40 using blink::protocol::Debugger::StackTrace; |
| 41 using blink::protocol::Runtime::RemoteObject; |
| 41 | 42 |
| 42 namespace blink { | 43 namespace blink { |
| 43 | 44 |
| 44 namespace DebuggerAgentState { | 45 namespace DebuggerAgentState { |
| 45 static const char javaScriptBreakpoints[] = "javaScriptBreakopints"; | 46 static const char javaScriptBreakpoints[] = "javaScriptBreakopints"; |
| 46 static const char pauseOnExceptionsState[] = "pauseOnExceptionsState"; | 47 static const char pauseOnExceptionsState[] = "pauseOnExceptionsState"; |
| 47 static const char asyncCallStackDepth[] = "asyncCallStackDepth"; | 48 static const char asyncCallStackDepth[] = "asyncCallStackDepth"; |
| 48 static const char promiseTrackerEnabled[] = "promiseTrackerEnabled"; | 49 static const char promiseTrackerEnabled[] = "promiseTrackerEnabled"; |
| 49 static const char promiseTrackerCaptureStacks[] = "promiseTrackerCaptureStacks"; | 50 static const char promiseTrackerCaptureStacks[] = "promiseTrackerCaptureStacks"; |
| 50 | 51 |
| 51 // Breakpoint properties. | 52 // Breakpoint properties. |
| 52 static const char url[] = "url"; | 53 static const char url[] = "url"; |
| 53 static const char isRegex[] = "isRegex"; | 54 static const char isRegex[] = "isRegex"; |
| 54 static const char lineNumber[] = "lineNumber"; | 55 static const char lineNumber[] = "lineNumber"; |
| 55 static const char columnNumber[] = "columnNumber"; | 56 static const char columnNumber[] = "columnNumber"; |
| 56 static const char condition[] = "condition"; | 57 static const char condition[] = "condition"; |
| 57 static const char skipAllPauses[] = "skipAllPauses"; | 58 static const char skipAllPauses[] = "skipAllPauses"; |
| 58 | 59 |
| 59 } // namespace DebuggerAgentState; | 60 } // namespace DebuggerAgentState; |
| 60 | 61 |
| 61 inline static bool asBool(const bool* const b) | |
| 62 { | |
| 63 return b ? *b : false; | |
| 64 } | |
| 65 | |
| 66 static const int maxSkipStepFrameCount = 128; | 62 static const int maxSkipStepFrameCount = 128; |
| 67 | 63 |
| 68 const char V8DebuggerAgent::backtraceObjectGroup[] = "backtrace"; | 64 const char V8DebuggerAgent::backtraceObjectGroup[] = "backtrace"; |
| 69 | 65 |
| 70 const int V8DebuggerAgent::unknownAsyncOperationId = 0; | 66 const int V8DebuggerAgent::unknownAsyncOperationId = 0; |
| 71 | 67 |
| 72 static String breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source) | 68 static String breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source) |
| 73 { | 69 { |
| 74 switch (source) { | 70 switch (source) { |
| 75 case V8DebuggerAgentImpl::UserBreakpointSource: | 71 case V8DebuggerAgentImpl::UserBreakpointSource: |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 } | 119 } |
| 124 | 120 |
| 125 V8DebuggerAgentImpl::V8DebuggerAgentImpl(InjectedScriptManager* injectedScriptMa
nager, V8DebuggerImpl* debugger, int contextGroupId) | 121 V8DebuggerAgentImpl::V8DebuggerAgentImpl(InjectedScriptManager* injectedScriptMa
nager, V8DebuggerImpl* debugger, int contextGroupId) |
| 126 : m_injectedScriptManager(injectedScriptManager) | 122 : m_injectedScriptManager(injectedScriptManager) |
| 127 , m_debugger(debugger) | 123 , m_debugger(debugger) |
| 128 , m_contextGroupId(contextGroupId) | 124 , m_contextGroupId(contextGroupId) |
| 129 , m_enabled(false) | 125 , m_enabled(false) |
| 130 , m_state(nullptr) | 126 , m_state(nullptr) |
| 131 , m_frontend(nullptr) | 127 , m_frontend(nullptr) |
| 132 , m_isolate(debugger->isolate()) | 128 , m_isolate(debugger->isolate()) |
| 133 , m_breakReason(protocol::Frontend::Debugger::Reason::Other) | 129 , m_breakReason(protocol::Debugger::Paused::ReasonEnum::Other) |
| 134 , m_scheduledDebuggerStep(NoStep) | 130 , m_scheduledDebuggerStep(NoStep) |
| 135 , m_skipNextDebuggerStepOut(false) | 131 , m_skipNextDebuggerStepOut(false) |
| 136 , m_javaScriptPauseScheduled(false) | 132 , m_javaScriptPauseScheduled(false) |
| 137 , m_steppingFromFramework(false) | 133 , m_steppingFromFramework(false) |
| 138 , m_pausingOnNativeEvent(false) | 134 , m_pausingOnNativeEvent(false) |
| 139 , m_pausingOnAsyncOperation(false) | 135 , m_pausingOnAsyncOperation(false) |
| 140 , m_skippedStepFrameCount(0) | 136 , m_skippedStepFrameCount(0) |
| 141 , m_recursionLevelForStepOut(0) | 137 , m_recursionLevelForStepOut(0) |
| 142 , m_recursionLevelForStepFrame(0) | 138 , m_recursionLevelForStepFrame(0) |
| 143 , m_skipAllPauses(false) | 139 , m_skipAllPauses(false) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 | 300 |
| 305 static bool matches(V8DebuggerImpl* debugger, const String& url, const String& p
attern, bool isRegex) | 301 static bool matches(V8DebuggerImpl* debugger, const String& url, const String& p
attern, bool isRegex) |
| 306 { | 302 { |
| 307 if (isRegex) { | 303 if (isRegex) { |
| 308 V8Regex regex(debugger, pattern, TextCaseSensitive); | 304 V8Regex regex(debugger, pattern, TextCaseSensitive); |
| 309 return regex.match(url) != -1; | 305 return regex.match(url) != -1; |
| 310 } | 306 } |
| 311 return url == pattern; | 307 return url == pattern; |
| 312 } | 308 } |
| 313 | 309 |
| 314 void V8DebuggerAgentImpl::setBreakpointByUrl(ErrorString* errorString, int lineN
umber, const String* const optionalURL, const String* const optionalURLRegex, co
nst int* const optionalColumnNumber, const String* const optionalCondition, Brea
kpointId* outBreakpointId, RefPtr<Array<protocol::TypeBuilder::Debugger::Locatio
n>>& locations) | 310 void V8DebuggerAgentImpl::setBreakpointByUrl(ErrorString* errorString, |
| 311 int lineNumber, |
| 312 const OptionalValue<String>& optionalURL, |
| 313 const OptionalValue<String>& optionalURLRegex, |
| 314 const OptionalValue<int>& optionalColumnNumber, |
| 315 const OptionalValue<String>& optionalCondition, |
| 316 BreakpointId* outBreakpointId, |
| 317 OwnPtr<protocol::Array<protocol::Debugger::Location>>* locations) |
| 315 { | 318 { |
| 316 locations = Array<protocol::TypeBuilder::Debugger::Location>::create(); | 319 *locations = Array<protocol::Debugger::Location>::create(); |
| 317 if (!optionalURL == !optionalURLRegex) { | 320 if (optionalURL.hasValue() == optionalURLRegex.hasValue()) { |
| 318 *errorString = "Either url or urlRegex must be specified."; | 321 *errorString = "Either url or urlRegex must be specified."; |
| 319 return; | 322 return; |
| 320 } | 323 } |
| 321 | 324 |
| 322 String url = optionalURL ? *optionalURL : *optionalURLRegex; | 325 String url = optionalURL.hasValue() ? optionalURL.get() : optionalURLRegex.g
et(); |
| 323 int columnNumber = 0; | 326 int columnNumber = 0; |
| 324 if (optionalColumnNumber) { | 327 if (optionalColumnNumber.hasValue()) { |
| 325 columnNumber = *optionalColumnNumber; | 328 columnNumber = optionalColumnNumber.get(); |
| 326 if (columnNumber < 0) { | 329 if (columnNumber < 0) { |
| 327 *errorString = "Incorrect column number"; | 330 *errorString = "Incorrect column number"; |
| 328 return; | 331 return; |
| 329 } | 332 } |
| 330 } | 333 } |
| 331 String condition = optionalCondition ? *optionalCondition : ""; | 334 String condition = optionalCondition.get(""); |
| 332 bool isRegex = optionalURLRegex; | 335 bool isRegex = optionalURLRegex.hasValue(); |
| 333 | 336 |
| 334 String breakpointId = (isRegex ? "/" + url + "/" : url) + ':' + String::numb
er(lineNumber) + ':' + String::number(columnNumber); | 337 String breakpointId = (isRegex ? "/" + url + "/" : url) + ':' + String::numb
er(lineNumber) + ':' + String::number(columnNumber); |
| 335 RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState
::javaScriptBreakpoints); | 338 RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState
::javaScriptBreakpoints); |
| 336 if (!breakpointsCookie) { | 339 if (!breakpointsCookie) { |
| 337 breakpointsCookie = JSONObject::create(); | 340 breakpointsCookie = JSONObject::create(); |
| 338 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpoint
sCookie); | 341 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpoint
sCookie); |
| 339 } | 342 } |
| 340 if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end()) { | 343 if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end()) { |
| 341 *errorString = "Breakpoint at specified location already exists."; | 344 *errorString = "Breakpoint at specified location already exists."; |
| 342 return; | 345 return; |
| 343 } | 346 } |
| 344 | 347 |
| 345 breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(ur
l, lineNumber, columnNumber, condition, isRegex)); | 348 breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(ur
l, lineNumber, columnNumber, condition, isRegex)); |
| 346 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCoo
kie); | 349 m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCoo
kie); |
| 347 | 350 |
| 348 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 351 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); |
| 349 for (auto& script : m_scripts) { | 352 for (auto& script : m_scripts) { |
| 350 if (!matches(m_debugger, script.value.sourceURL(), url, isRegex)) | 353 if (!matches(m_debugger, script.value.sourceURL(), url, isRegex)) |
| 351 continue; | 354 continue; |
| 352 RefPtr<protocol::TypeBuilder::Debugger::Location> location = resolveBrea
kpoint(breakpointId, script.key, breakpoint, UserBreakpointSource); | 355 OwnPtr<protocol::Debugger::Location> location = resolveBreakpoint(breakp
ointId, script.key, breakpoint, UserBreakpointSource); |
| 353 if (location) | 356 if (location) |
| 354 locations->addItem(location); | 357 (*locations)->addItem(location.release()); |
| 355 } | 358 } |
| 356 | 359 |
| 357 *outBreakpointId = breakpointId; | 360 *outBreakpointId = breakpointId; |
| 358 } | 361 } |
| 359 | 362 |
| 360 static bool parseLocation(ErrorString* errorString, PassRefPtr<JSONObject> locat
ion, String* scriptId, int* lineNumber, int* columnNumber) | 363 static bool parseLocation(ErrorString* errorString, PassOwnPtr<protocol::Debugge
r::Location> location, String* scriptId, int* lineNumber, int* columnNumber) |
| 361 { | 364 { |
| 362 if (!location->getString("scriptId", scriptId) || !location->getNumber("line
Number", lineNumber)) { | 365 if (!location->hasScriptId() || !location->hasLineNumber()) { |
| 363 // FIXME: replace with input validation. | 366 // FIXME: replace with input validation. |
| 364 *errorString = "scriptId and lineNumber are required."; | 367 *errorString = "scriptId and lineNumber are required."; |
| 365 return false; | 368 return false; |
| 366 } | 369 } |
| 367 *columnNumber = 0; | 370 *scriptId = location->getScriptId(); |
| 368 location->getNumber("columnNumber", columnNumber); | 371 *lineNumber = location->getLineNumber(); |
| 372 *columnNumber = location->getColumnNumber(0); |
| 369 return true; | 373 return true; |
| 370 } | 374 } |
| 371 | 375 |
| 372 void V8DebuggerAgentImpl::setBreakpoint(ErrorString* errorString, const RefPtr<J
SONObject>& location, const String* const optionalCondition, BreakpointId* outBr
eakpointId, RefPtr<protocol::TypeBuilder::Debugger::Location>& actualLocation) | 376 void V8DebuggerAgentImpl::setBreakpoint(ErrorString* errorString, |
| 377 PassOwnPtr<protocol::Debugger::Location> location, |
| 378 const OptionalValue<String>& optionalCondition, |
| 379 BreakpointId* outBreakpointId, |
| 380 OwnPtr<protocol::Debugger::Location>* actualLocation) |
| 373 { | 381 { |
| 374 String scriptId; | 382 String scriptId; |
| 375 int lineNumber; | 383 int lineNumber; |
| 376 int columnNumber; | 384 int columnNumber; |
| 377 | 385 |
| 378 if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNum
ber)) | 386 if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNum
ber)) |
| 379 return; | 387 return; |
| 380 | 388 |
| 381 String condition = optionalCondition ? *optionalCondition : emptyString(); | 389 String condition = optionalCondition.get(""); |
| 382 | 390 |
| 383 String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumbe
r, UserBreakpointSource); | 391 String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumbe
r, UserBreakpointSource); |
| 384 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != m_breakpoint
IdToDebuggerBreakpointIds.end()) { | 392 if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != m_breakpoint
IdToDebuggerBreakpointIds.end()) { |
| 385 *errorString = "Breakpoint at specified location already exists."; | 393 *errorString = "Breakpoint at specified location already exists."; |
| 386 return; | 394 return; |
| 387 } | 395 } |
| 388 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 396 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); |
| 389 actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, UserB
reakpointSource); | 397 *actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, User
BreakpointSource); |
| 390 if (actualLocation) | 398 if (*actualLocation) |
| 391 *outBreakpointId = breakpointId; | 399 *outBreakpointId = breakpointId; |
| 392 else | 400 else |
| 393 *errorString = "Could not resolve breakpoint"; | 401 *errorString = "Could not resolve breakpoint"; |
| 394 } | 402 } |
| 395 | 403 |
| 396 void V8DebuggerAgentImpl::removeBreakpoint(ErrorString* errorString, const Strin
g& breakpointId) | 404 void V8DebuggerAgentImpl::removeBreakpoint(ErrorString* errorString, const Strin
g& breakpointId) |
| 397 { | 405 { |
| 398 if (!checkEnabled(errorString)) | 406 if (!checkEnabled(errorString)) |
| 399 return; | 407 return; |
| 400 RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState
::javaScriptBreakpoints); | 408 RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState
::javaScriptBreakpoints); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 411 return; | 419 return; |
| 412 for (size_t i = 0; i < debuggerBreakpointIdsIterator->value.size(); ++i) { | 420 for (size_t i = 0; i < debuggerBreakpointIdsIterator->value.size(); ++i) { |
| 413 const String& debuggerBreakpointId = debuggerBreakpointIdsIterator->valu
e[i]; | 421 const String& debuggerBreakpointId = debuggerBreakpointIdsIterator->valu
e[i]; |
| 414 debugger().removeBreakpoint(debuggerBreakpointId); | 422 debugger().removeBreakpoint(debuggerBreakpointId); |
| 415 m_serverBreakpoints.remove(debuggerBreakpointId); | 423 m_serverBreakpoints.remove(debuggerBreakpointId); |
| 416 m_muteBreakpoints.remove(debuggerBreakpointId); | 424 m_muteBreakpoints.remove(debuggerBreakpointId); |
| 417 } | 425 } |
| 418 m_breakpointIdToDebuggerBreakpointIds.remove(debuggerBreakpointIdsIterator); | 426 m_breakpointIdToDebuggerBreakpointIds.remove(debuggerBreakpointIdsIterator); |
| 419 } | 427 } |
| 420 | 428 |
| 421 void V8DebuggerAgentImpl::continueToLocation(ErrorString* errorString, const Ref
Ptr<JSONObject>& location, const bool* interstateLocationOpt) | 429 void V8DebuggerAgentImpl::continueToLocation(ErrorString* errorString, |
| 430 PassOwnPtr<protocol::Debugger::Location> location, |
| 431 const protocol::OptionalValue<bool>& interstateLocationOpt) |
| 422 { | 432 { |
| 423 if (!checkEnabled(errorString)) | 433 if (!checkEnabled(errorString)) |
| 424 return; | 434 return; |
| 425 if (!m_continueToLocationBreakpointId.isEmpty()) { | 435 if (!m_continueToLocationBreakpointId.isEmpty()) { |
| 426 debugger().removeBreakpoint(m_continueToLocationBreakpointId); | 436 debugger().removeBreakpoint(m_continueToLocationBreakpointId); |
| 427 m_continueToLocationBreakpointId = ""; | 437 m_continueToLocationBreakpointId = ""; |
| 428 } | 438 } |
| 429 | 439 |
| 430 String scriptId; | 440 String scriptId; |
| 431 int lineNumber; | 441 int lineNumber; |
| 432 int columnNumber; | 442 int columnNumber; |
| 433 | 443 |
| 434 if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNum
ber)) | 444 if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNum
ber)) |
| 435 return; | 445 return; |
| 436 | 446 |
| 437 ScriptBreakpoint breakpoint(lineNumber, columnNumber, ""); | 447 ScriptBreakpoint breakpoint(lineNumber, columnNumber, ""); |
| 438 m_continueToLocationBreakpointId = debugger().setBreakpoint(scriptId, breakp
oint, &lineNumber, &columnNumber, asBool(interstateLocationOpt)); | 448 m_continueToLocationBreakpointId = debugger().setBreakpoint(scriptId, breakp
oint, &lineNumber, &columnNumber, interstateLocationOpt.get(false)); |
| 439 resume(errorString); | 449 resume(errorString); |
| 440 } | 450 } |
| 441 | 451 |
| 442 void V8DebuggerAgentImpl::getStepInPositions(ErrorString* errorString, const Str
ing& callFrameId, RefPtr<Array<protocol::TypeBuilder::Debugger::Location>>& posi
tions) | 452 void V8DebuggerAgentImpl::getStepInPositions(ErrorString* errorString, const Str
ing& callFrameId, OwnPtr<Array<protocol::Debugger::Location>>* positions) |
| 443 { | 453 { |
| 444 if (!isPaused() || m_currentCallStack.IsEmpty()) { | 454 if (!isPaused() || m_currentCallStack.IsEmpty()) { |
| 445 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 455 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
| 446 return; | 456 return; |
| 447 } | 457 } |
| 448 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameId); | 458 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameId); |
| 449 if (!remoteId) { | 459 if (!remoteId) { |
| 450 *errorString = "Invalid call frame id"; | 460 *errorString = "Invalid call frame id"; |
| 451 return; | 461 return; |
| 452 } | 462 } |
| 453 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); | 463 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); |
| 454 if (!injectedScript) { | 464 if (!injectedScript) { |
| 455 *errorString = "Inspected frame has gone"; | 465 *errorString = "Inspected frame has gone"; |
| 456 return; | 466 return; |
| 457 } | 467 } |
| 458 | 468 |
| 459 v8::HandleScope scope(m_isolate); | 469 v8::HandleScope scope(m_isolate); |
| 460 v8::Local<v8::Object> callStack = m_currentCallStack.Get(m_isolate); | 470 v8::Local<v8::Object> callStack = m_currentCallStack.Get(m_isolate); |
| 461 injectedScript->getStepInPositions(errorString, callStack, callFrameId, posi
tions); | 471 injectedScript->getStepInPositions(errorString, callStack, callFrameId, posi
tions); |
| 462 } | 472 } |
| 463 | 473 |
| 464 void V8DebuggerAgentImpl::getBacktrace(ErrorString* errorString, RefPtr<Array<Ca
llFrame>>& callFrames, RefPtr<StackTrace>& asyncStackTrace) | 474 void V8DebuggerAgentImpl::getBacktrace(ErrorString* errorString, OwnPtr<Array<Ca
llFrame>>* callFrames, OwnPtr<StackTrace>* asyncStackTrace) |
| 465 { | 475 { |
| 466 if (!assertPaused(errorString)) | 476 if (!assertPaused(errorString)) |
| 467 return; | 477 return; |
| 468 m_currentCallStack.Reset(m_isolate, debugger().currentCallFrames()); | 478 m_currentCallStack.Reset(m_isolate, debugger().currentCallFrames()); |
| 469 callFrames = currentCallFrames(); | 479 *callFrames = currentCallFrames(); |
| 470 asyncStackTrace = currentAsyncStackTrace(); | 480 *asyncStackTrace = currentAsyncStackTrace(); |
| 471 } | 481 } |
| 472 | 482 |
| 473 bool V8DebuggerAgentImpl::isCallStackEmptyOrBlackboxed() | 483 bool V8DebuggerAgentImpl::isCallStackEmptyOrBlackboxed() |
| 474 { | 484 { |
| 475 ASSERT(enabled()); | 485 ASSERT(enabled()); |
| 476 for (int index = 0; ; ++index) { | 486 for (int index = 0; ; ++index) { |
| 477 RefPtr<JavaScriptCallFrame> frame = debugger().callFrameNoScopes(index); | 487 RefPtr<JavaScriptCallFrame> frame = debugger().callFrameNoScopes(index); |
| 478 if (!frame) | 488 if (!frame) |
| 479 break; | 489 break; |
| 480 if (!isCallFrameWithUnknownScriptOrBlackboxed(frame.release())) | 490 if (!isCallFrameWithUnknownScriptOrBlackboxed(frame.release())) |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 if (m_skippedStepFrameCount >= maxSkipStepFrameCount) | 562 if (m_skippedStepFrameCount >= maxSkipStepFrameCount) |
| 553 return RequestStepOut; | 563 return RequestStepOut; |
| 554 | 564 |
| 555 if (!m_skippedStepFrameCount) | 565 if (!m_skippedStepFrameCount) |
| 556 m_recursionLevelForStepFrame = 1; | 566 m_recursionLevelForStepFrame = 1; |
| 557 | 567 |
| 558 ++m_skippedStepFrameCount; | 568 ++m_skippedStepFrameCount; |
| 559 return RequestStepFrame; | 569 return RequestStepFrame; |
| 560 } | 570 } |
| 561 | 571 |
| 562 PassRefPtr<protocol::TypeBuilder::Debugger::Location> V8DebuggerAgentImpl::resol
veBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBre
akpoint& breakpoint, BreakpointSource source) | 572 PassOwnPtr<protocol::Debugger::Location> V8DebuggerAgentImpl::resolveBreakpoint(
const String& breakpointId, const String& scriptId, const ScriptBreakpoint& brea
kpoint, BreakpointSource source) |
| 563 { | 573 { |
| 564 ASSERT(enabled()); | 574 ASSERT(enabled()); |
| 565 // FIXME: remove these checks once crbug.com/520702 is resolved. | 575 // FIXME: remove these checks once crbug.com/520702 is resolved. |
| 566 RELEASE_ASSERT(!breakpointId.isEmpty()); | 576 RELEASE_ASSERT(!breakpointId.isEmpty()); |
| 567 RELEASE_ASSERT(!scriptId.isEmpty()); | 577 RELEASE_ASSERT(!scriptId.isEmpty()); |
| 568 ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); | 578 ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); |
| 569 if (scriptIterator == m_scripts.end()) | 579 if (scriptIterator == m_scripts.end()) |
| 570 return nullptr; | 580 return nullptr; |
| 571 V8DebuggerScript& script = scriptIterator->value; | 581 V8DebuggerScript& script = scriptIterator->value; |
| 572 if (breakpoint.lineNumber < script.startLine() || script.endLine() < breakpo
int.lineNumber) | 582 if (breakpoint.lineNumber < script.startLine() || script.endLine() < breakpo
int.lineNumber) |
| 573 return nullptr; | 583 return nullptr; |
| 574 | 584 |
| 575 int actualLineNumber; | 585 int actualLineNumber; |
| 576 int actualColumnNumber; | 586 int actualColumnNumber; |
| 577 String debuggerBreakpointId = debugger().setBreakpoint(scriptId, breakpoint,
&actualLineNumber, &actualColumnNumber, false); | 587 String debuggerBreakpointId = debugger().setBreakpoint(scriptId, breakpoint,
&actualLineNumber, &actualColumnNumber, false); |
| 578 if (debuggerBreakpointId.isEmpty()) | 588 if (debuggerBreakpointId.isEmpty()) |
| 579 return nullptr; | 589 return nullptr; |
| 580 | 590 |
| 581 m_serverBreakpoints.set(debuggerBreakpointId, std::make_pair(breakpointId, s
ource)); | 591 m_serverBreakpoints.set(debuggerBreakpointId, std::make_pair(breakpointId, s
ource)); |
| 582 if (breakpoint.condition == "false") | 592 if (breakpoint.condition == "false") |
| 583 m_muteBreakpoints.set(debuggerBreakpointId, std::make_pair(scriptId, bre
akpoint.lineNumber)); | 593 m_muteBreakpoints.set(debuggerBreakpointId, std::make_pair(scriptId, bre
akpoint.lineNumber)); |
| 584 | 594 |
| 585 RELEASE_ASSERT(!breakpointId.isEmpty()); | 595 RELEASE_ASSERT(!breakpointId.isEmpty()); |
| 586 BreakpointIdToDebuggerBreakpointIdsMap::iterator debuggerBreakpointIdsIterat
or = m_breakpointIdToDebuggerBreakpointIds.find(breakpointId); | 596 BreakpointIdToDebuggerBreakpointIdsMap::iterator debuggerBreakpointIdsIterat
or = m_breakpointIdToDebuggerBreakpointIds.find(breakpointId); |
| 587 if (debuggerBreakpointIdsIterator == m_breakpointIdToDebuggerBreakpointIds.e
nd()) | 597 if (debuggerBreakpointIdsIterator == m_breakpointIdToDebuggerBreakpointIds.e
nd()) |
| 588 m_breakpointIdToDebuggerBreakpointIds.set(breakpointId, Vector<String>()
).storedValue->value.append(debuggerBreakpointId); | 598 m_breakpointIdToDebuggerBreakpointIds.set(breakpointId, Vector<String>()
).storedValue->value.append(debuggerBreakpointId); |
| 589 else | 599 else |
| 590 debuggerBreakpointIdsIterator->value.append(debuggerBreakpointId); | 600 debuggerBreakpointIdsIterator->value.append(debuggerBreakpointId); |
| 591 | 601 |
| 592 RefPtr<protocol::TypeBuilder::Debugger::Location> location = protocol::TypeB
uilder::Debugger::Location::create() | 602 OwnPtr<protocol::Debugger::Location> location = protocol::Debugger::Location
::create() |
| 593 .setScriptId(scriptId) | 603 .setScriptId(scriptId) |
| 594 .setLineNumber(actualLineNumber); | 604 .setLineNumber(actualLineNumber) |
| 595 location->setColumnNumber(actualColumnNumber); | 605 .setColumnNumber(actualColumnNumber).build(); |
| 596 return location; | 606 return location.release(); |
| 597 } | 607 } |
| 598 | 608 |
| 599 void V8DebuggerAgentImpl::searchInContent(ErrorString* error, const String& scri
ptId, const String& query, const bool* const optionalCaseSensitive, const bool*
const optionalIsRegex, RefPtr<Array<protocol::TypeBuilder::Debugger::SearchMatch
>>& results) | 609 void V8DebuggerAgentImpl::searchInContent(ErrorString* error, const String& scri
ptId, const String& query, |
| 610 const OptionalValue<bool>& optionalCaseSensitive, |
| 611 const OptionalValue<bool>& optionalIsRegex, |
| 612 OwnPtr<Array<protocol::Debugger::SearchMatch>>* results) |
| 600 { | 613 { |
| 601 ScriptsMap::iterator it = m_scripts.find(scriptId); | 614 ScriptsMap::iterator it = m_scripts.find(scriptId); |
| 602 if (it != m_scripts.end()) | 615 if (it != m_scripts.end()) |
| 603 results = V8ContentSearchUtil::searchInTextByLines(m_debugger, it->value
.source(), query, asBool(optionalCaseSensitive), asBool(optionalIsRegex)); | 616 *results = V8ContentSearchUtil::searchInTextByLines(m_debugger, it->valu
e.source(), query, optionalCaseSensitive.get(false), optionalIsRegex.get(false))
; |
| 604 else | 617 else |
| 605 *error = "No script for id: " + scriptId; | 618 *error = "No script for id: " + scriptId; |
| 606 } | 619 } |
| 607 | 620 |
| 608 void V8DebuggerAgentImpl::setScriptSource(ErrorString* error, const String& scri
ptId, const String& newContent, const bool* const preview, RefPtr<Array<CallFram
e>>& newCallFrames, protocol::TypeBuilder::OptOutput<bool>* stackChanged, RefPtr
<StackTrace>& asyncStackTrace, RefPtr<protocol::TypeBuilder::Debugger::SetScript
SourceError>& optOutCompileError) | 621 void V8DebuggerAgentImpl::setScriptSource(ErrorString* error, |
| 622 const String& scriptId, |
| 623 const String& newContent, |
| 624 const OptionalValue<bool>& preview, |
| 625 OwnPtr<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames, |
| 626 OptionalValue<bool>* stackChanged, |
| 627 OwnPtr<StackTrace>* asyncStackTrace, |
| 628 OwnPtr<protocol::Debugger::SetScriptSourceError>* optOutCompileError) |
| 609 { | 629 { |
| 610 if (!checkEnabled(error)) | 630 if (!checkEnabled(error)) |
| 611 return; | 631 return; |
| 612 if (!debugger().setScriptSource(scriptId, newContent, asBool(preview), error
, optOutCompileError, &m_currentCallStack, stackChanged)) | 632 if (!debugger().setScriptSource(scriptId, newContent, preview.get(false), er
ror, optOutCompileError, &m_currentCallStack, stackChanged)) |
| 613 return; | 633 return; |
| 614 | 634 |
| 615 newCallFrames = currentCallFrames(); | 635 *newCallFrames = currentCallFrames(); |
| 616 asyncStackTrace = currentAsyncStackTrace(); | 636 *asyncStackTrace = currentAsyncStackTrace(); |
| 617 | 637 |
| 618 ScriptsMap::iterator it = m_scripts.find(scriptId); | 638 ScriptsMap::iterator it = m_scripts.find(scriptId); |
| 619 if (it == m_scripts.end()) | 639 if (it == m_scripts.end()) |
| 620 return; | 640 return; |
| 621 it->value.setSource(newContent); | 641 it->value.setSource(newContent); |
| 622 } | 642 } |
| 623 | 643 |
| 624 void V8DebuggerAgentImpl::restartFrame(ErrorString* errorString, const String& c
allFrameId, RefPtr<Array<CallFrame>>& newCallFrames, RefPtr<StackTrace>& asyncSt
ackTrace) | 644 void V8DebuggerAgentImpl::restartFrame(ErrorString* errorString, |
| 645 const String& callFrameId, |
| 646 OwnPtr<Array<CallFrame>>* newCallFrames, |
| 647 OwnPtr<StackTrace>* asyncStackTrace) |
| 625 { | 648 { |
| 626 if (!isPaused() || m_currentCallStack.IsEmpty()) { | 649 if (!isPaused() || m_currentCallStack.IsEmpty()) { |
| 627 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 650 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
| 628 return; | 651 return; |
| 629 } | 652 } |
| 630 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameId); | 653 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameId); |
| 631 if (!remoteId) { | 654 if (!remoteId) { |
| 632 *errorString = "Invalid call frame id"; | 655 *errorString = "Invalid call frame id"; |
| 633 return; | 656 return; |
| 634 } | 657 } |
| 635 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); | 658 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); |
| 636 if (!injectedScript) { | 659 if (!injectedScript) { |
| 637 *errorString = "Inspected frame has gone"; | 660 *errorString = "Inspected frame has gone"; |
| 638 return; | 661 return; |
| 639 } | 662 } |
| 640 | 663 |
| 641 v8::HandleScope scope(m_isolate); | 664 v8::HandleScope scope(m_isolate); |
| 642 v8::Local<v8::Object> callStack = m_currentCallStack.Get(m_isolate); | 665 v8::Local<v8::Object> callStack = m_currentCallStack.Get(m_isolate); |
| 643 injectedScript->restartFrame(errorString, callStack, callFrameId); | 666 injectedScript->restartFrame(errorString, callStack, callFrameId); |
| 644 m_currentCallStack.Reset(m_isolate, debugger().currentCallFrames()); | 667 m_currentCallStack.Reset(m_isolate, debugger().currentCallFrames()); |
| 645 newCallFrames = currentCallFrames(); | 668 *newCallFrames = currentCallFrames(); |
| 646 asyncStackTrace = currentAsyncStackTrace(); | 669 *asyncStackTrace = currentAsyncStackTrace(); |
| 647 } | 670 } |
| 648 | 671 |
| 649 void V8DebuggerAgentImpl::getScriptSource(ErrorString* error, const String& scri
ptId, String* scriptSource) | 672 void V8DebuggerAgentImpl::getScriptSource(ErrorString* error, const String& scri
ptId, String* scriptSource) |
| 650 { | 673 { |
| 651 if (!checkEnabled(error)) | 674 if (!checkEnabled(error)) |
| 652 return; | 675 return; |
| 653 ScriptsMap::iterator it = m_scripts.find(scriptId); | 676 ScriptsMap::iterator it = m_scripts.find(scriptId); |
| 654 if (it == m_scripts.end()) { | 677 if (it == m_scripts.end()) { |
| 655 *error = "No script for id: " + scriptId; | 678 *error = "No script for id: " + scriptId; |
| 656 return; | 679 return; |
| 657 } | 680 } |
| 658 *scriptSource = it->value.source(); | 681 *scriptSource = it->value.source(); |
| 659 } | 682 } |
| 660 | 683 |
| 661 void V8DebuggerAgentImpl::getFunctionDetails(ErrorString* errorString, const Str
ing& functionId, RefPtr<FunctionDetails>& details) | 684 void V8DebuggerAgentImpl::getFunctionDetails(ErrorString* errorString, const Str
ing& functionId, OwnPtr<FunctionDetails>* details) |
| 662 { | 685 { |
| 663 if (!checkEnabled(errorString)) | 686 if (!checkEnabled(errorString)) |
| 664 return; | 687 return; |
| 665 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(functionId); | 688 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(functionId); |
| 666 if (!remoteId) { | 689 if (!remoteId) { |
| 667 *errorString = "Invalid object id"; | 690 *errorString = "Invalid object id"; |
| 668 return; | 691 return; |
| 669 } | 692 } |
| 670 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); | 693 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); |
| 671 if (!injectedScript) { | 694 if (!injectedScript) { |
| 672 *errorString = "Function object id is obsolete"; | 695 *errorString = "Function object id is obsolete"; |
| 673 return; | 696 return; |
| 674 } | 697 } |
| 675 injectedScript->getFunctionDetails(errorString, functionId, &details); | 698 injectedScript->getFunctionDetails(errorString, functionId, details); |
| 676 } | 699 } |
| 677 | 700 |
| 678 void V8DebuggerAgentImpl::getGeneratorObjectDetails(ErrorString* errorString, co
nst String& objectId, RefPtr<GeneratorObjectDetails>& details) | 701 void V8DebuggerAgentImpl::getGeneratorObjectDetails(ErrorString* errorString, co
nst String& objectId, OwnPtr<GeneratorObjectDetails>* details) |
| 679 { | 702 { |
| 680 if (!checkEnabled(errorString)) | 703 if (!checkEnabled(errorString)) |
| 681 return; | 704 return; |
| 682 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(objectId); | 705 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(objectId); |
| 683 if (!remoteId) { | 706 if (!remoteId) { |
| 684 *errorString = "Invalid object id"; | 707 *errorString = "Invalid object id"; |
| 685 return; | 708 return; |
| 686 } | 709 } |
| 687 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); | 710 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); |
| 688 if (!injectedScript) { | 711 if (!injectedScript) { |
| 689 *errorString = "Inspected frame has gone"; | 712 *errorString = "Inspected frame has gone"; |
| 690 return; | 713 return; |
| 691 } | 714 } |
| 692 injectedScript->getGeneratorObjectDetails(errorString, objectId, &details); | 715 injectedScript->getGeneratorObjectDetails(errorString, objectId, details); |
| 693 } | 716 } |
| 694 | 717 |
| 695 void V8DebuggerAgentImpl::getCollectionEntries(ErrorString* errorString, const S
tring& objectId, RefPtr<protocol::TypeBuilder::Array<CollectionEntry>>& entries) | 718 void V8DebuggerAgentImpl::getCollectionEntries(ErrorString* errorString, const S
tring& objectId, OwnPtr<protocol::Array<CollectionEntry>>* entries) |
| 696 { | 719 { |
| 697 if (!checkEnabled(errorString)) | 720 if (!checkEnabled(errorString)) |
| 698 return; | 721 return; |
| 699 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(objectId); | 722 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(objectId); |
| 700 if (!remoteId) { | 723 if (!remoteId) { |
| 701 *errorString = "Invalid object id"; | 724 *errorString = "Invalid object id"; |
| 702 return; | 725 return; |
| 703 } | 726 } |
| 704 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); | 727 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); |
| 705 if (!injectedScript) { | 728 if (!injectedScript) { |
| 706 *errorString = "Inspected frame has gone"; | 729 *errorString = "Inspected frame has gone"; |
| 707 return; | 730 return; |
| 708 } | 731 } |
| 709 injectedScript->getCollectionEntries(errorString, objectId, &entries); | 732 injectedScript->getCollectionEntries(errorString, objectId, entries); |
| 710 } | 733 } |
| 711 | 734 |
| 712 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(protocol::Frontend::Debug
ger::Reason::Enum breakReason, PassRefPtr<JSONObject> data) | 735 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(const String& breakReason
, PassRefPtr<JSONObject> data) |
| 713 { | 736 { |
| 714 ASSERT(enabled()); | 737 ASSERT(enabled()); |
| 715 if (m_scheduledDebuggerStep == StepInto || m_javaScriptPauseScheduled || isP
aused()) | 738 if (m_scheduledDebuggerStep == StepInto || m_javaScriptPauseScheduled || isP
aused()) |
| 716 return; | 739 return; |
| 717 m_breakReason = breakReason; | 740 m_breakReason = breakReason; |
| 718 m_breakAuxData = data; | 741 m_breakAuxData = data; |
| 719 m_pausingOnNativeEvent = true; | 742 m_pausingOnNativeEvent = true; |
| 720 m_skipNextDebuggerStepOut = false; | 743 m_skipNextDebuggerStepOut = false; |
| 721 debugger().setPauseOnNextStatement(true); | 744 debugger().setPauseOnNextStatement(true); |
| 722 } | 745 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 if (!m_currentAsyncCallChain || asyncOrdinal < 1 || asyncOrdinal > m_current
AsyncCallChain->callStacks().size()) { | 901 if (!m_currentAsyncCallChain || asyncOrdinal < 1 || asyncOrdinal > m_current
AsyncCallChain->callStacks().size()) { |
| 879 *errorString = "Async call stack not found"; | 902 *errorString = "Async call stack not found"; |
| 880 return false; | 903 return false; |
| 881 } | 904 } |
| 882 RefPtr<AsyncCallStack> asyncStack = m_currentAsyncCallChain->callStacks()[as
yncOrdinal - 1]; | 905 RefPtr<AsyncCallStack> asyncStack = m_currentAsyncCallChain->callStacks()[as
yncOrdinal - 1]; |
| 883 *callStack = asyncStack->callFrames(m_isolate); | 906 *callStack = asyncStack->callFrames(m_isolate); |
| 884 *isAsync = true; | 907 *isAsync = true; |
| 885 return true; | 908 return true; |
| 886 } | 909 } |
| 887 | 910 |
| 888 void V8DebuggerAgentImpl::evaluateOnCallFrame(ErrorString* errorString, const St
ring& callFrameId, const String& expression, const String* const objectGroup, co
nst bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsA
ndMuteConsole, const bool* const returnByValue, const bool* generatePreview, Ref
Ptr<RemoteObject>& result, protocol::TypeBuilder::OptOutput<bool>* wasThrown, Re
fPtr<protocol::TypeBuilder::Runtime::ExceptionDetails>& exceptionDetails) | 911 void V8DebuggerAgentImpl::evaluateOnCallFrame(ErrorString* errorString, |
| 912 const String& callFrameId, |
| 913 const String& expression, |
| 914 const OptionalValue<String>& objectGroup, |
| 915 const OptionalValue<bool>& includeCommandLineAPI, |
| 916 const OptionalValue<bool>& doNotPauseOnExceptionsAndMuteConsole, |
| 917 const OptionalValue<bool>& returnByValue, |
| 918 const OptionalValue<bool>& generatePreview, |
| 919 OwnPtr<RemoteObject>* result, |
| 920 OptionalValue<bool>* wasThrown, |
| 921 OwnPtr<protocol::Runtime::ExceptionDetails>* exceptionDetails) |
| 889 { | 922 { |
| 890 if (!isPaused() || m_currentCallStack.IsEmpty()) { | 923 if (!isPaused() || m_currentCallStack.IsEmpty()) { |
| 891 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 924 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
| 892 return; | 925 return; |
| 893 } | 926 } |
| 894 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameId); | 927 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameId); |
| 895 if (!remoteId) { | 928 if (!remoteId) { |
| 896 *errorString = "Invalid call frame id"; | 929 *errorString = "Invalid call frame id"; |
| 897 return; | 930 return; |
| 898 } | 931 } |
| 899 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); | 932 InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript
(remoteId.get()); |
| 900 if (!injectedScript) { | 933 if (!injectedScript) { |
| 901 *errorString = "Inspected frame has gone"; | 934 *errorString = "Inspected frame has gone"; |
| 902 return; | 935 return; |
| 903 } | 936 } |
| 904 | 937 |
| 905 v8::HandleScope scope(m_isolate); | 938 v8::HandleScope scope(m_isolate); |
| 906 bool isAsync = false; | 939 bool isAsync = false; |
| 907 v8::Local<v8::Object> callStack; | 940 v8::Local<v8::Object> callStack; |
| 908 if (!callStackForId(errorString, *remoteId, &callStack, &isAsync)) | 941 if (!callStackForId(errorString, *remoteId, &callStack, &isAsync)) |
| 909 return; | 942 return; |
| 910 ASSERT(!callStack.IsEmpty()); | 943 ASSERT(!callStack.IsEmpty()); |
| 911 | 944 |
| 912 Optional<IgnoreExceptionsScope> ignoreExceptionsScope; | 945 Optional<IgnoreExceptionsScope> ignoreExceptionsScope; |
| 913 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) | 946 if (doNotPauseOnExceptionsAndMuteConsole.get(false)) |
| 914 ignoreExceptionsScope.emplace(m_debugger); | 947 ignoreExceptionsScope.emplace(m_debugger); |
| 915 | 948 |
| 916 injectedScript->evaluateOnCallFrame(errorString, callStack, isAsync, callFra
meId, expression, objectGroup ? *objectGroup : "", asBool(includeCommandLineAPI)
, asBool(returnByValue), asBool(generatePreview), &result, wasThrown, &exception
Details); | 949 injectedScript->evaluateOnCallFrame(errorString, callStack, isAsync, callFra
meId, expression, objectGroup.get(""), includeCommandLineAPI.get(false), returnB
yValue.get(false), generatePreview.get(false), result, wasThrown, exceptionDetai
ls); |
| 917 } | 950 } |
| 918 | 951 |
| 919 void V8DebuggerAgentImpl::setVariableValue(ErrorString* errorString, int scopeNu
mber, const String& variableName, const RefPtr<JSONObject>& newValue, const Stri
ng* callFrameId, const String* functionObjectId) | 952 void V8DebuggerAgentImpl::setVariableValue(ErrorString* errorString, |
| 953 int scopeNumber, |
| 954 const String& variableName, |
| 955 PassOwnPtr<protocol::Runtime::CallArgument> newValue, |
| 956 const OptionalValue<String>& callFrameId, |
| 957 const OptionalValue<String>& functionObjectId) |
| 920 { | 958 { |
| 921 if (!checkEnabled(errorString)) | 959 if (!checkEnabled(errorString)) |
| 922 return; | 960 return; |
| 923 InjectedScript* injectedScript = nullptr; | 961 InjectedScript* injectedScript = nullptr; |
| 924 if (callFrameId) { | 962 if (callFrameId.hasValue()) { |
| 925 if (!isPaused() || m_currentCallStack.IsEmpty()) { | 963 if (!isPaused() || m_currentCallStack.IsEmpty()) { |
| 926 *errorString = "Attempt to access callframe when debugger is not on
pause"; | 964 *errorString = "Attempt to access callframe when debugger is not on
pause"; |
| 927 return; | 965 return; |
| 928 } | 966 } |
| 929 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(*callFrame
Id); | 967 OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(callFrameI
d.get()); |
| 930 if (!remoteId) { | 968 if (!remoteId) { |
| 931 *errorString = "Invalid call frame id"; | 969 *errorString = "Invalid call frame id"; |
| 932 return; | 970 return; |
| 933 } | 971 } |
| 934 injectedScript = m_injectedScriptManager->findInjectedScript(remoteId.ge
t()); | 972 injectedScript = m_injectedScriptManager->findInjectedScript(remoteId.ge
t()); |
| 935 if (!injectedScript) { | 973 if (!injectedScript) { |
| 936 *errorString = "Inspected frame has gone"; | 974 *errorString = "Inspected frame has gone"; |
| 937 return; | 975 return; |
| 938 } | 976 } |
| 939 } else if (functionObjectId) { | 977 } else if (functionObjectId.hasValue()) { |
| 940 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(*functionObjectI
d); | 978 OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(functionObjectId
.get()); |
| 941 if (!remoteId) { | 979 if (!remoteId) { |
| 942 *errorString = "Invalid object id"; | 980 *errorString = "Invalid object id"; |
| 943 return; | 981 return; |
| 944 } | 982 } |
| 945 injectedScript = m_injectedScriptManager->findInjectedScript(remoteId.ge
t()); | 983 injectedScript = m_injectedScriptManager->findInjectedScript(remoteId.ge
t()); |
| 946 if (!injectedScript) { | 984 if (!injectedScript) { |
| 947 *errorString = "Function object id cannot be resolved"; | 985 *errorString = "Function object id cannot be resolved"; |
| 948 return; | 986 return; |
| 949 } | 987 } |
| 950 } else { | 988 } else { |
| 951 *errorString = "Either call frame or function object must be specified"; | 989 *errorString = "Either call frame or function object must be specified"; |
| 952 return; | 990 return; |
| 953 } | 991 } |
| 954 String newValueString = newValue->toJSONString(); | 992 String newValueString = protocol::toValue(newValue)->toJSONString(); |
| 955 | |
| 956 v8::HandleScope scope(m_isolate); | 993 v8::HandleScope scope(m_isolate); |
| 957 v8::Local<v8::Object> currentCallStack = m_currentCallStack.Get(m_isolate); | 994 v8::Local<v8::Object> currentCallStack = m_currentCallStack.Get(m_isolate); |
| 958 injectedScript->setVariableValue(errorString, currentCallStack, callFrameId,
functionObjectId, scopeNumber, variableName, newValueString); | 995 injectedScript->setVariableValue(errorString, currentCallStack, callFrameId,
functionObjectId, scopeNumber, variableName, newValueString); |
| 959 } | 996 } |
| 960 | 997 |
| 961 void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString, int d
epth) | 998 void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString, int d
epth) |
| 962 { | 999 { |
| 963 if (!checkEnabled(errorString)) | 1000 if (!checkEnabled(errorString)) |
| 964 return; | 1001 return; |
| 965 m_state->setNumber(DebuggerAgentState::asyncCallStackDepth, depth); | 1002 m_state->setNumber(DebuggerAgentState::asyncCallStackDepth, depth); |
| 966 internalSetAsyncCallStackDepth(depth); | 1003 internalSetAsyncCallStackDepth(depth); |
| 967 } | 1004 } |
| 968 | 1005 |
| 969 void V8DebuggerAgentImpl::enablePromiseTracker(ErrorString* errorString, const b
ool* captureStacks) | 1006 void V8DebuggerAgentImpl::enablePromiseTracker(ErrorString* errorString, |
| 1007 const OptionalValue<bool>& captureStacks) |
| 970 { | 1008 { |
| 971 if (!checkEnabled(errorString)) | 1009 if (!checkEnabled(errorString)) |
| 972 return; | 1010 return; |
| 973 m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, true); | 1011 m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, true); |
| 974 m_state->setBoolean(DebuggerAgentState::promiseTrackerCaptureStacks, asBool(
captureStacks)); | 1012 m_state->setBoolean(DebuggerAgentState::promiseTrackerCaptureStacks, capture
Stacks.get(false)); |
| 975 m_promiseTracker->setEnabled(true, asBool(captureStacks)); | 1013 m_promiseTracker->setEnabled(true, captureStacks.get(false)); |
| 976 } | 1014 } |
| 977 | 1015 |
| 978 void V8DebuggerAgentImpl::disablePromiseTracker(ErrorString* errorString) | 1016 void V8DebuggerAgentImpl::disablePromiseTracker(ErrorString* errorString) |
| 979 { | 1017 { |
| 980 if (!checkEnabled(errorString)) | 1018 if (!checkEnabled(errorString)) |
| 981 return; | 1019 return; |
| 982 m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, false); | 1020 m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, false); |
| 983 m_promiseTracker->setEnabled(false, false); | 1021 m_promiseTracker->setEnabled(false, false); |
| 984 } | 1022 } |
| 985 | 1023 |
| 986 void V8DebuggerAgentImpl::getPromiseById(ErrorString* errorString, int promiseId
, const String* objectGroup, RefPtr<RemoteObject>& promise) | 1024 void V8DebuggerAgentImpl::getPromiseById(ErrorString* errorString, int promiseId
, const OptionalValue<String>& objectGroup, OwnPtr<RemoteObject>* promise) |
| 987 { | 1025 { |
| 988 if (!checkEnabled(errorString)) | 1026 if (!checkEnabled(errorString)) |
| 989 return; | 1027 return; |
| 990 if (!m_promiseTracker->isEnabled()) { | 1028 if (!m_promiseTracker->isEnabled()) { |
| 991 *errorString = "Promise tracking is disabled"; | 1029 *errorString = "Promise tracking is disabled"; |
| 992 return; | 1030 return; |
| 993 } | 1031 } |
| 994 v8::HandleScope handles(m_isolate); | 1032 v8::HandleScope handles(m_isolate); |
| 995 v8::Local<v8::Object> value = m_promiseTracker->promiseById(promiseId); | 1033 v8::Local<v8::Object> value = m_promiseTracker->promiseById(promiseId); |
| 996 if (value.IsEmpty()) { | 1034 if (value.IsEmpty()) { |
| 997 *errorString = "Promise with specified ID not found."; | 1035 *errorString = "Promise with specified ID not found."; |
| 998 return; | 1036 return; |
| 999 } | 1037 } |
| 1000 InjectedScript* injectedScript = m_injectedScriptManager->injectedScriptFor(
value->CreationContext()); | 1038 InjectedScript* injectedScript = m_injectedScriptManager->injectedScriptFor(
value->CreationContext()); |
| 1001 promise = injectedScript->wrapObject(value, objectGroup ? *objectGroup : "")
; | 1039 *promise = injectedScript->wrapObject(value, objectGroup.get("")); |
| 1002 } | 1040 } |
| 1003 | 1041 |
| 1004 void V8DebuggerAgentImpl::didUpdatePromise(protocol::Frontend::Debugger::EventTy
pe::Enum eventType, PassRefPtr<protocol::TypeBuilder::Debugger::PromiseDetails>
promise) | 1042 void V8DebuggerAgentImpl::didUpdatePromise(const String& eventType, PassOwnPtr<p
rotocol::Debugger::PromiseDetails> promise) |
| 1005 { | 1043 { |
| 1006 if (m_frontend) | 1044 if (m_frontend) |
| 1007 m_frontend->promiseUpdated(eventType, promise); | 1045 m_frontend->promiseUpdated(eventType, promise); |
| 1008 } | 1046 } |
| 1009 | 1047 |
| 1010 int V8DebuggerAgentImpl::traceAsyncOperationStarting(const String& description) | 1048 int V8DebuggerAgentImpl::traceAsyncOperationStarting(const String& description) |
| 1011 { | 1049 { |
| 1012 v8::HandleScope scope(m_isolate); | 1050 v8::HandleScope scope(m_isolate); |
| 1013 v8::Local<v8::Object> callFrames = debugger().currentCallFramesForAsyncStack
(); | 1051 v8::Local<v8::Object> callFrames = debugger().currentCallFramesForAsyncStack
(); |
| 1014 RefPtr<AsyncCallChain> chain; | 1052 RefPtr<AsyncCallChain> chain; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 v8::Local<v8::Object> callFrames = callStacks.at(i)->callFrames(m_is
olate); | 1184 v8::Local<v8::Object> callFrames = callStacks.at(i)->callFrames(m_is
olate); |
| 1147 RefPtr<JavaScriptCallFrame> jsCallFrame = toJavaScriptCallFrame(chai
n->creationContext(m_isolate), callFrames); | 1185 RefPtr<JavaScriptCallFrame> jsCallFrame = toJavaScriptCallFrame(chai
n->creationContext(m_isolate), callFrames); |
| 1148 if (!jsCallFrame) | 1186 if (!jsCallFrame) |
| 1149 continue; | 1187 continue; |
| 1150 Vector<V8StackTraceImpl::Frame> frames; | 1188 Vector<V8StackTraceImpl::Frame> frames; |
| 1151 toScriptCallFrames(jsCallFrame.get(), frames); | 1189 toScriptCallFrames(jsCallFrame.get(), frames); |
| 1152 stack = V8StackTraceImpl::create(callStacks.at(i)->description(), fr
ames, stack.release()); | 1190 stack = V8StackTraceImpl::create(callStacks.at(i)->description(), fr
ames, stack.release()); |
| 1153 } | 1191 } |
| 1154 | 1192 |
| 1155 if (stack) { | 1193 if (stack) { |
| 1156 RefPtr<AsyncOperation> operation = AsyncOperation::create() | 1194 OwnPtr<AsyncOperation> operation = AsyncOperation::create() |
| 1157 .setId(operationId) | 1195 .setId(operationId) |
| 1158 .release(); | 1196 .setStack(stack->buildInspectorObject()).build(); |
| 1159 operation->setStack(stack->buildInspectorObject()); | |
| 1160 m_frontend->asyncOperationStarted(operation.release()); | 1197 m_frontend->asyncOperationStarted(operation.release()); |
| 1161 } | 1198 } |
| 1162 } | 1199 } |
| 1163 | 1200 |
| 1164 m_asyncOperationNotifications.clear(); | 1201 m_asyncOperationNotifications.clear(); |
| 1165 } | 1202 } |
| 1166 | 1203 |
| 1167 void V8DebuggerAgentImpl::clearCurrentAsyncOperation() | 1204 void V8DebuggerAgentImpl::clearCurrentAsyncOperation() |
| 1168 { | 1205 { |
| 1169 if (m_pendingTraceAsyncOperationCompleted && m_currentAsyncOperationId != un
knownAsyncOperationId) | 1206 if (m_pendingTraceAsyncOperationCompleted && m_currentAsyncOperationId != un
knownAsyncOperationId) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 *errorString = "Can only perform operation while tracking async call sta
cks."; | 1245 *errorString = "Can only perform operation while tracking async call sta
cks."; |
| 1209 return; | 1246 return; |
| 1210 } | 1247 } |
| 1211 if (operationId <= 0) { | 1248 if (operationId <= 0) { |
| 1212 *errorString = "Wrong async operation id."; | 1249 *errorString = "Wrong async operation id."; |
| 1213 return; | 1250 return; |
| 1214 } | 1251 } |
| 1215 m_asyncOperationBreakpoints.remove(operationId); | 1252 m_asyncOperationBreakpoints.remove(operationId); |
| 1216 } | 1253 } |
| 1217 | 1254 |
| 1218 void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String&
scriptId, const RefPtr<JSONArray>& inPositions) | 1255 void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String&
scriptId, PassOwnPtr<protocol::Array<protocol::Debugger::ScriptPosition>> inPosi
tions) |
| 1219 { | 1256 { |
| 1220 ScriptsMap::iterator it = m_scripts.find(scriptId); | 1257 ScriptsMap::iterator it = m_scripts.find(scriptId); |
| 1221 if (it == m_scripts.end()) { | 1258 if (it == m_scripts.end()) { |
| 1222 *error = "No script with passed id."; | 1259 *error = "No script with passed id."; |
| 1223 return; | 1260 return; |
| 1224 } | 1261 } |
| 1225 | 1262 |
| 1226 if (!inPositions->length()) { | 1263 if (!inPositions->length()) { |
| 1227 m_blackboxedPositions.remove(scriptId); | 1264 m_blackboxedPositions.remove(scriptId); |
| 1228 return; | 1265 return; |
| 1229 } | 1266 } |
| 1230 | 1267 |
| 1231 Vector<std::pair<int, int>> positions(inPositions->length()); | 1268 Vector<std::pair<int, int>> positions(inPositions->length()); |
| 1232 for (size_t i = 0; i < positions.size(); ++i) { | 1269 for (size_t i = 0; i < positions.size(); ++i) { |
| 1233 RefPtr<JSONObject> positionObj; | 1270 OwnPtr<protocol::Debugger::ScriptPosition> position = inPositions->get(i
); |
| 1234 int line = 0; | 1271 if (!position->hasLine() || position->getLine() < 0) { |
| 1235 int column = 0; | |
| 1236 inPositions->get(i)->asObject(&positionObj); | |
| 1237 if (!positionObj->getNumber("line", &line) || line < 0) { | |
| 1238 *error = "Position missing 'line' or 'line' < 0."; | 1272 *error = "Position missing 'line' or 'line' < 0."; |
| 1239 return; | 1273 return; |
| 1240 } | 1274 } |
| 1241 if (!positionObj->getNumber("column", &column) || column < 0) { | 1275 if (!position->hasColumn() || position->getColumn() < 0) { |
| 1242 *error = "Position missing 'column' or 'column' < 0."; | 1276 *error = "Position missing 'column' or 'column' < 0."; |
| 1243 return; | 1277 return; |
| 1244 } | 1278 } |
| 1245 positions[i] = std::make_pair(line, column); | 1279 positions[i] = std::make_pair(position->getLine(), position->getColumn()
); |
| 1246 } | 1280 } |
| 1247 | 1281 |
| 1248 for (size_t i = 1; i < positions.size(); ++i) { | 1282 for (size_t i = 1; i < positions.size(); ++i) { |
| 1249 if (positions[i - 1].first < positions[i].first) | 1283 if (positions[i - 1].first < positions[i].first) |
| 1250 continue; | 1284 continue; |
| 1251 if (positions[i - 1].first == positions[i].first && positions[i - 1].sec
ond < positions[i].second) | 1285 if (positions[i - 1].first == positions[i].first && positions[i - 1].sec
ond < positions[i].second) |
| 1252 continue; | 1286 continue; |
| 1253 *error = "Input positions array is not sorted or contains duplicate valu
es."; | 1287 *error = "Input positions array is not sorted or contains duplicate valu
es."; |
| 1254 return; | 1288 return; |
| 1255 } | 1289 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 // from the old StepFrame. | 1334 // from the old StepFrame. |
| 1301 m_skippedStepFrameCount = 0; | 1335 m_skippedStepFrameCount = 0; |
| 1302 if (m_scheduledDebuggerStep == NoStep) | 1336 if (m_scheduledDebuggerStep == NoStep) |
| 1303 debugger().clearStepping(); | 1337 debugger().clearStepping(); |
| 1304 else if (m_scheduledDebuggerStep == StepOut) | 1338 else if (m_scheduledDebuggerStep == StepOut) |
| 1305 m_skipNextDebuggerStepOut = true; | 1339 m_skipNextDebuggerStepOut = true; |
| 1306 } | 1340 } |
| 1307 } | 1341 } |
| 1308 } | 1342 } |
| 1309 | 1343 |
| 1310 PassRefPtr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames() | 1344 PassOwnPtr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames() |
| 1311 { | 1345 { |
| 1312 if (m_pausedContext.IsEmpty() || m_currentCallStack.IsEmpty()) | 1346 if (m_pausedContext.IsEmpty() || m_currentCallStack.IsEmpty()) |
| 1313 return Array<CallFrame>::create(); | 1347 return Array<CallFrame>::create(); |
| 1314 v8::HandleScope handles(m_isolate); | 1348 v8::HandleScope handles(m_isolate); |
| 1315 InjectedScript* injectedScript = m_injectedScriptManager->injectedScriptFor(
m_pausedContext.Get(m_isolate)); | 1349 InjectedScript* injectedScript = m_injectedScriptManager->injectedScriptFor(
m_pausedContext.Get(m_isolate)); |
| 1316 if (!injectedScript) { | 1350 if (!injectedScript) { |
| 1317 // Context has been reported as removed while on pause. | 1351 // Context has been reported as removed while on pause. |
| 1318 return Array<CallFrame>::create(); | 1352 return Array<CallFrame>::create(); |
| 1319 } | 1353 } |
| 1320 | 1354 |
| 1321 v8::Local<v8::Object> currentCallStack = m_currentCallStack.Get(m_isolate); | 1355 v8::Local<v8::Object> currentCallStack = m_currentCallStack.Get(m_isolate); |
| 1322 return injectedScript->wrapCallFrames(currentCallStack, 0); | 1356 return injectedScript->wrapCallFrames(currentCallStack, 0); |
| 1323 } | 1357 } |
| 1324 | 1358 |
| 1325 PassRefPtr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() | 1359 PassOwnPtr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() |
| 1326 { | 1360 { |
| 1327 if (m_pausedContext.IsEmpty() || !trackingAsyncCalls()) | 1361 if (m_pausedContext.IsEmpty() || !trackingAsyncCalls()) |
| 1328 return nullptr; | 1362 return nullptr; |
| 1329 const AsyncCallChain* chain = m_currentAsyncCallChain.get(); | 1363 const AsyncCallChain* chain = m_currentAsyncCallChain.get(); |
| 1330 if (!chain) | 1364 if (!chain) |
| 1331 return nullptr; | 1365 return nullptr; |
| 1332 const AsyncCallStackVector& callStacks = chain->callStacks(); | 1366 const AsyncCallStackVector& callStacks = chain->callStacks(); |
| 1333 if (callStacks.isEmpty()) | 1367 if (callStacks.isEmpty()) |
| 1334 return nullptr; | 1368 return nullptr; |
| 1335 RefPtr<StackTrace> result; | 1369 OwnPtr<StackTrace> result; |
| 1336 int asyncOrdinal = callStacks.size(); | 1370 int asyncOrdinal = callStacks.size(); |
| 1337 for (AsyncCallStackVector::const_reverse_iterator it = callStacks.rbegin();
it != callStacks.rend(); ++it, --asyncOrdinal) { | 1371 for (AsyncCallStackVector::const_reverse_iterator it = callStacks.rbegin();
it != callStacks.rend(); ++it, --asyncOrdinal) { |
| 1338 v8::HandleScope scope(m_isolate); | 1372 v8::HandleScope scope(m_isolate); |
| 1339 v8::Local<v8::Object> callFrames = (*it)->callFrames(m_isolate); | 1373 v8::Local<v8::Object> callFrames = (*it)->callFrames(m_isolate); |
| 1340 InjectedScript* injectedScript = m_injectedScriptManager->injectedScript
For(callFrames->CreationContext()); | 1374 InjectedScript* injectedScript = m_injectedScriptManager->injectedScript
For(callFrames->CreationContext()); |
| 1341 if (!injectedScript) { | 1375 if (!injectedScript) { |
| 1342 result.clear(); | 1376 result.clear(); |
| 1343 continue; | 1377 continue; |
| 1344 } | 1378 } |
| 1345 RefPtr<StackTrace> next = StackTrace::create() | 1379 OwnPtr<StackTrace> next = StackTrace::create() |
| 1346 .setCallFrames(injectedScript->wrapCallFrames(callFrames, asyncOrdin
al)) | 1380 .setCallFrames(injectedScript->wrapCallFrames(callFrames, asyncOrdin
al)) |
| 1347 .release(); | 1381 .setDescription((*it)->description()).build(); |
| 1348 next->setDescription((*it)->description()); | |
| 1349 if (result) | 1382 if (result) |
| 1350 next->setAsyncStackTrace(result.release()); | 1383 next->setAsyncStackTrace(result.release()); |
| 1351 result.swap(next); | 1384 result.swap(next); |
| 1352 } | 1385 } |
| 1353 return result.release(); | 1386 return result.release(); |
| 1354 } | 1387 } |
| 1355 | 1388 |
| 1356 PassOwnPtr<V8StackTraceImpl> V8DebuggerAgentImpl::currentAsyncStackTraceForRunti
me() | 1389 PassOwnPtr<V8StackTraceImpl> V8DebuggerAgentImpl::currentAsyncStackTraceForRunti
me() |
| 1357 { | 1390 { |
| 1358 if (!trackingAsyncCalls()) | 1391 if (!trackingAsyncCalls()) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 | 1427 |
| 1395 int executionContextId = script.executionContextId(); | 1428 int executionContextId = script.executionContextId(); |
| 1396 bool isContentScript = script.isContentScript(); | 1429 bool isContentScript = script.isContentScript(); |
| 1397 bool isInternalScript = script.isInternalScript(); | 1430 bool isInternalScript = script.isInternalScript(); |
| 1398 bool isLiveEdit = script.isLiveEdit(); | 1431 bool isLiveEdit = script.isLiveEdit(); |
| 1399 bool hasSourceURL = script.hasSourceURL(); | 1432 bool hasSourceURL = script.hasSourceURL(); |
| 1400 String scriptURL = script.sourceURL(); | 1433 String scriptURL = script.sourceURL(); |
| 1401 String sourceMapURL = script.sourceMappingURL(); | 1434 String sourceMapURL = script.sourceMappingURL(); |
| 1402 bool deprecatedCommentWasUsed = isDeprecatedSourceURL || isDeprecatedSourceM
appingURL; | 1435 bool deprecatedCommentWasUsed = isDeprecatedSourceURL || isDeprecatedSourceM
appingURL; |
| 1403 | 1436 |
| 1404 const String* sourceMapURLParam = sourceMapURL.isNull() ? nullptr : &sourceM
apURL; | 1437 OptionalValue<String> sourceMapURLParam = sourceMapURL; |
| 1405 const bool* isContentScriptParam = isContentScript ? &isContentScript : null
ptr; | 1438 const bool* isContentScriptParam = isContentScript ? &isContentScript : null
ptr; |
| 1406 const bool* isInternalScriptParam = isInternalScript ? &isInternalScript : n
ullptr; | 1439 const bool* isInternalScriptParam = isInternalScript ? &isInternalScript : n
ullptr; |
| 1407 const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; | 1440 const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; |
| 1408 const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; | 1441 const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; |
| 1409 const bool* deprecatedCommentWasUsedParam = deprecatedCommentWasUsed ? &depr
ecatedCommentWasUsed : nullptr; | 1442 const bool* deprecatedCommentWasUsedParam = deprecatedCommentWasUsed ? &depr
ecatedCommentWasUsed : nullptr; |
| 1410 if (parsedScript.success) | 1443 if (parsedScript.success) |
| 1411 m_frontend->scriptParsed(parsedScript.scriptId, scriptURL, script.startL
ine(), script.startColumn(), script.endLine(), script.endColumn(), executionCont
extId, isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapUR
LParam, hasSourceURLParam, deprecatedCommentWasUsedParam); | 1444 m_frontend->scriptParsed(parsedScript.scriptId, scriptURL, script.startL
ine(), script.startColumn(), script.endLine(), script.endColumn(), executionCont
extId, isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapUR
LParam, hasSourceURLParam, deprecatedCommentWasUsedParam); |
| 1412 else | 1445 else |
| 1413 m_frontend->scriptFailedToParse(parsedScript.scriptId, scriptURL, script
.startLine(), script.startColumn(), script.endLine(), script.endColumn(), execut
ionContextId, isContentScriptParam, isInternalScriptParam, sourceMapURLParam, ha
sSourceURLParam, deprecatedCommentWasUsedParam); | 1446 m_frontend->scriptFailedToParse(parsedScript.scriptId, scriptURL, script
.startLine(), script.startColumn(), script.endLine(), script.endColumn(), execut
ionContextId, isContentScriptParam, isInternalScriptParam, sourceMapURLParam, ha
sSourceURLParam, deprecatedCommentWasUsedParam); |
| 1414 | 1447 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1426 bool isRegex; | 1459 bool isRegex; |
| 1427 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); | 1460 breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); |
| 1428 String url; | 1461 String url; |
| 1429 breakpointObject->getString(DebuggerAgentState::url, &url); | 1462 breakpointObject->getString(DebuggerAgentState::url, &url); |
| 1430 if (!matches(m_debugger, scriptURL, url, isRegex)) | 1463 if (!matches(m_debugger, scriptURL, url, isRegex)) |
| 1431 continue; | 1464 continue; |
| 1432 ScriptBreakpoint breakpoint; | 1465 ScriptBreakpoint breakpoint; |
| 1433 breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakpoint.
lineNumber); | 1466 breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakpoint.
lineNumber); |
| 1434 breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakpoin
t.columnNumber); | 1467 breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakpoin
t.columnNumber); |
| 1435 breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.c
ondition); | 1468 breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.c
ondition); |
| 1436 RefPtr<protocol::TypeBuilder::Debugger::Location> location = resolveBrea
kpoint(cookie.key, parsedScript.scriptId, breakpoint, UserBreakpointSource); | 1469 OwnPtr<protocol::Debugger::Location> location = resolveBreakpoint(cookie
.key, parsedScript.scriptId, breakpoint, UserBreakpointSource); |
| 1437 if (location) | 1470 if (location) |
| 1438 m_frontend->breakpointResolved(cookie.key, location); | 1471 m_frontend->breakpointResolved(cookie.key, location.release()); |
| 1439 } | 1472 } |
| 1440 } | 1473 } |
| 1441 | 1474 |
| 1442 V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::Local<v8
::Context> context, v8::Local<v8::Object> callFrames, v8::Local<v8::Value> excep
tion, const Vector<String>& hitBreakpoints, bool isPromiseRejection) | 1475 V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::Local<v8
::Context> context, v8::Local<v8::Object> callFrames, v8::Local<v8::Value> excep
tion, const Vector<String>& hitBreakpoints, bool isPromiseRejection) |
| 1443 { | 1476 { |
| 1444 if (isMuteBreakpointInstalled()) | 1477 if (isMuteBreakpointInstalled()) |
| 1445 return RequestContinue; | 1478 return RequestContinue; |
| 1446 | 1479 |
| 1447 V8DebuggerAgentImpl::SkipPauseRequest result; | 1480 V8DebuggerAgentImpl::SkipPauseRequest result; |
| 1448 if (m_skipAllPauses) | 1481 if (m_skipAllPauses) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1465 return RequestContinue; | 1498 return RequestContinue; |
| 1466 | 1499 |
| 1467 ASSERT(m_pausedContext.IsEmpty()); | 1500 ASSERT(m_pausedContext.IsEmpty()); |
| 1468 m_pausedContext.Reset(m_isolate, context); | 1501 m_pausedContext.Reset(m_isolate, context); |
| 1469 m_currentCallStack.Reset(m_isolate, callFrames); | 1502 m_currentCallStack.Reset(m_isolate, callFrames); |
| 1470 v8::HandleScope handles(m_isolate); | 1503 v8::HandleScope handles(m_isolate); |
| 1471 | 1504 |
| 1472 if (!exception.IsEmpty()) { | 1505 if (!exception.IsEmpty()) { |
| 1473 InjectedScript* injectedScript = m_injectedScriptManager->injectedScript
For(context); | 1506 InjectedScript* injectedScript = m_injectedScriptManager->injectedScript
For(context); |
| 1474 if (injectedScript) { | 1507 if (injectedScript) { |
| 1475 m_breakReason = isPromiseRejection ? protocol::Frontend::Debugger::R
eason::PromiseRejection : protocol::Frontend::Debugger::Reason::Exception; | 1508 m_breakReason = isPromiseRejection ? protocol::Debugger::Paused::Rea
sonEnum::PromiseRejection : protocol::Debugger::Paused::ReasonEnum::Exception; |
| 1476 m_breakAuxData = injectedScript->wrapObject(exception, V8DebuggerAge
ntImpl::backtraceObjectGroup)->openAccessors(); | 1509 auto obj = injectedScript->wrapObject(exception, V8DebuggerAgentImpl
::backtraceObjectGroup); |
| 1510 m_breakAuxData = obj ? obj->asValue() : nullptr; |
| 1477 // m_breakAuxData might be null after this. | 1511 // m_breakAuxData might be null after this. |
| 1478 } | 1512 } |
| 1479 } else if (m_pausingOnAsyncOperation) { | 1513 } else if (m_pausingOnAsyncOperation) { |
| 1480 m_breakReason = protocol::Frontend::Debugger::Reason::AsyncOperation; | 1514 m_breakReason = protocol::Debugger::Paused::ReasonEnum::AsyncOperation; |
| 1481 m_breakAuxData = JSONObject::create(); | 1515 m_breakAuxData = JSONObject::create(); |
| 1482 m_breakAuxData->setNumber("operationId", m_currentAsyncOperationId); | 1516 m_breakAuxData->setNumber("operationId", m_currentAsyncOperationId); |
| 1483 } | 1517 } |
| 1484 | 1518 |
| 1485 RefPtr<Array<String>> hitBreakpointIds = Array<String>::create(); | 1519 OwnPtr<Array<String>> hitBreakpointIds = Array<String>::create(); |
| 1486 | 1520 |
| 1487 for (const auto& point : hitBreakpoints) { | 1521 for (const auto& point : hitBreakpoints) { |
| 1488 DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIter
ator = m_serverBreakpoints.find(point); | 1522 DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIter
ator = m_serverBreakpoints.find(point); |
| 1489 if (breakpointIterator != m_serverBreakpoints.end()) { | 1523 if (breakpointIterator != m_serverBreakpoints.end()) { |
| 1490 const String& localId = breakpointIterator->value.first; | 1524 const String& localId = breakpointIterator->value.first; |
| 1491 hitBreakpointIds->addItem(localId); | 1525 hitBreakpointIds->addItem(localId); |
| 1492 | 1526 |
| 1493 BreakpointSource source = breakpointIterator->value.second; | 1527 BreakpointSource source = breakpointIterator->value.second; |
| 1494 if (m_breakReason == protocol::Frontend::Debugger::Reason::Other &&
source == DebugCommandBreakpointSource) | 1528 if (m_breakReason == protocol::Debugger::Paused::ReasonEnum::Other &
& source == DebugCommandBreakpointSource) |
| 1495 m_breakReason = protocol::Frontend::Debugger::Reason::DebugComma
nd; | 1529 m_breakReason = protocol::Debugger::Paused::ReasonEnum::DebugCom
mand; |
| 1496 } | 1530 } |
| 1497 } | 1531 } |
| 1498 | 1532 |
| 1499 if (!m_asyncOperationNotifications.isEmpty()) | 1533 if (!m_asyncOperationNotifications.isEmpty()) |
| 1500 flushAsyncOperationEvents(nullptr); | 1534 flushAsyncOperationEvents(nullptr); |
| 1501 | 1535 |
| 1502 m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBr
eakpointIds, currentAsyncStackTrace()); | 1536 m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBr
eakpointIds.release(), currentAsyncStackTrace()); |
| 1503 m_scheduledDebuggerStep = NoStep; | 1537 m_scheduledDebuggerStep = NoStep; |
| 1504 m_javaScriptPauseScheduled = false; | 1538 m_javaScriptPauseScheduled = false; |
| 1505 m_steppingFromFramework = false; | 1539 m_steppingFromFramework = false; |
| 1506 m_pausingOnNativeEvent = false; | 1540 m_pausingOnNativeEvent = false; |
| 1507 m_skippedStepFrameCount = 0; | 1541 m_skippedStepFrameCount = 0; |
| 1508 m_recursionLevelForStepFrame = 0; | 1542 m_recursionLevelForStepFrame = 0; |
| 1509 clearStepIntoAsync(); | 1543 clearStepIntoAsync(); |
| 1510 | 1544 |
| 1511 if (!m_continueToLocationBreakpointId.isEmpty()) { | 1545 if (!m_continueToLocationBreakpointId.isEmpty()) { |
| 1512 debugger().removeBreakpoint(m_continueToLocationBreakpointId); | 1546 debugger().removeBreakpoint(m_continueToLocationBreakpointId); |
| 1513 m_continueToLocationBreakpointId = ""; | 1547 m_continueToLocationBreakpointId = ""; |
| 1514 } | 1548 } |
| 1515 return result; | 1549 return result; |
| 1516 } | 1550 } |
| 1517 | 1551 |
| 1518 void V8DebuggerAgentImpl::didContinue() | 1552 void V8DebuggerAgentImpl::didContinue() |
| 1519 { | 1553 { |
| 1520 m_pausedContext.Reset(); | 1554 m_pausedContext.Reset(); |
| 1521 m_currentCallStack.Reset(); | 1555 m_currentCallStack.Reset(); |
| 1522 clearBreakDetails(); | 1556 clearBreakDetails(); |
| 1523 m_frontend->resumed(); | 1557 m_frontend->resumed(); |
| 1524 } | 1558 } |
| 1525 | 1559 |
| 1526 bool V8DebuggerAgentImpl::canBreakProgram() | 1560 bool V8DebuggerAgentImpl::canBreakProgram() |
| 1527 { | 1561 { |
| 1528 return debugger().canBreakProgram(); | 1562 return debugger().canBreakProgram(); |
| 1529 } | 1563 } |
| 1530 | 1564 |
| 1531 void V8DebuggerAgentImpl::breakProgram(protocol::Frontend::Debugger::Reason::Enu
m breakReason, PassRefPtr<JSONObject> data) | 1565 void V8DebuggerAgentImpl::breakProgram(const String& breakReason, PassRefPtr<JSO
NObject> data) |
| 1532 { | 1566 { |
| 1533 ASSERT(enabled()); | 1567 ASSERT(enabled()); |
| 1534 if (m_skipAllPauses || !m_pausedContext.IsEmpty() || isCallStackEmptyOrBlack
boxed()) | 1568 if (m_skipAllPauses || !m_pausedContext.IsEmpty() || isCallStackEmptyOrBlack
boxed()) |
| 1535 return; | 1569 return; |
| 1536 m_breakReason = breakReason; | 1570 m_breakReason = breakReason; |
| 1537 m_breakAuxData = data; | 1571 m_breakAuxData = data; |
| 1538 m_scheduledDebuggerStep = NoStep; | 1572 m_scheduledDebuggerStep = NoStep; |
| 1539 m_steppingFromFramework = false; | 1573 m_steppingFromFramework = false; |
| 1540 m_pausingOnNativeEvent = false; | 1574 m_pausingOnNativeEvent = false; |
| 1541 clearStepIntoAsync(); | 1575 clearStepIntoAsync(); |
| 1542 debugger().breakProgram(); | 1576 debugger().breakProgram(); |
| 1543 } | 1577 } |
| 1544 | 1578 |
| 1545 void V8DebuggerAgentImpl::breakProgramOnException(protocol::Frontend::Debugger::
Reason::Enum breakReason, PassRefPtr<JSONObject> data) | 1579 void V8DebuggerAgentImpl::breakProgramOnException(const String& breakReason, Pas
sRefPtr<JSONObject> data) |
| 1546 { | 1580 { |
| 1547 if (m_debugger->pauseOnExceptionsState() == V8DebuggerImpl::DontPauseOnExcep
tions) | 1581 if (m_debugger->pauseOnExceptionsState() == V8DebuggerImpl::DontPauseOnExcep
tions) |
| 1548 return; | 1582 return; |
| 1549 breakProgram(breakReason, data); | 1583 breakProgram(breakReason, data); |
| 1550 } | 1584 } |
| 1551 | 1585 |
| 1552 void V8DebuggerAgentImpl::clearStepIntoAsync() | 1586 void V8DebuggerAgentImpl::clearStepIntoAsync() |
| 1553 { | 1587 { |
| 1554 m_startingStepIntoAsync = false; | 1588 m_startingStepIntoAsync = false; |
| 1555 m_pausingOnAsyncOperation = false; | 1589 m_pausingOnAsyncOperation = false; |
| 1556 m_pausingAsyncOperations.clear(); | 1590 m_pausingAsyncOperations.clear(); |
| 1557 } | 1591 } |
| 1558 | 1592 |
| 1559 bool V8DebuggerAgentImpl::assertPaused(ErrorString* errorString) | 1593 bool V8DebuggerAgentImpl::assertPaused(ErrorString* errorString) |
| 1560 { | 1594 { |
| 1561 if (m_pausedContext.IsEmpty()) { | 1595 if (m_pausedContext.IsEmpty()) { |
| 1562 *errorString = "Can only perform operation while paused."; | 1596 *errorString = "Can only perform operation while paused."; |
| 1563 return false; | 1597 return false; |
| 1564 } | 1598 } |
| 1565 return true; | 1599 return true; |
| 1566 } | 1600 } |
| 1567 | 1601 |
| 1568 void V8DebuggerAgentImpl::clearBreakDetails() | 1602 void V8DebuggerAgentImpl::clearBreakDetails() |
| 1569 { | 1603 { |
| 1570 m_breakReason = protocol::Frontend::Debugger::Reason::Other; | 1604 m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other; |
| 1571 m_breakAuxData = nullptr; | 1605 m_breakAuxData = nullptr; |
| 1572 } | 1606 } |
| 1573 | 1607 |
| 1574 void V8DebuggerAgentImpl::setBreakpointAt(const String& scriptId, int lineNumber
, int columnNumber, BreakpointSource source, const String& condition) | 1608 void V8DebuggerAgentImpl::setBreakpointAt(const String& scriptId, int lineNumber
, int columnNumber, BreakpointSource source, const String& condition) |
| 1575 { | 1609 { |
| 1576 String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumbe
r, source); | 1610 String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumbe
r, source); |
| 1577 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); | 1611 ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); |
| 1578 resolveBreakpoint(breakpointId, scriptId, breakpoint, source); | 1612 resolveBreakpoint(breakpointId, scriptId, breakpoint, source); |
| 1579 } | 1613 } |
| 1580 | 1614 |
| 1581 void V8DebuggerAgentImpl::removeBreakpointAt(const String& scriptId, int lineNum
ber, int columnNumber, BreakpointSource source) | 1615 void V8DebuggerAgentImpl::removeBreakpointAt(const String& scriptId, int lineNum
ber, int columnNumber, BreakpointSource source) |
| 1582 { | 1616 { |
| 1583 removeBreakpoint(generateBreakpointId(scriptId, lineNumber, columnNumber, so
urce)); | 1617 removeBreakpoint(generateBreakpointId(scriptId, lineNumber, columnNumber, so
urce)); |
| 1584 } | 1618 } |
| 1585 | 1619 |
| 1586 void V8DebuggerAgentImpl::reset() | 1620 void V8DebuggerAgentImpl::reset() |
| 1587 { | 1621 { |
| 1588 m_scheduledDebuggerStep = NoStep; | 1622 m_scheduledDebuggerStep = NoStep; |
| 1589 m_scripts.clear(); | 1623 m_scripts.clear(); |
| 1590 m_blackboxedPositions.clear(); | 1624 m_blackboxedPositions.clear(); |
| 1591 m_breakpointIdToDebuggerBreakpointIds.clear(); | 1625 m_breakpointIdToDebuggerBreakpointIds.clear(); |
| 1592 resetAsyncCallTracker(); | 1626 resetAsyncCallTracker(); |
| 1593 m_promiseTracker->clear(); | 1627 m_promiseTracker->clear(); |
| 1594 if (m_frontend) | 1628 if (m_frontend) |
| 1595 m_frontend->globalObjectCleared(); | 1629 m_frontend->globalObjectCleared(); |
| 1596 } | 1630 } |
| 1597 | 1631 |
| 1598 } // namespace blink | 1632 } // namespace blink |
| OLD | NEW |