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

Unified Diff: Source/core/inspector/InspectorDebuggerAgent.cpp

Issue 74063002: DevTools: Support asynchronous call stacks on backend. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Async call stacks are off by default, added Debugger.enableAsyncCallStacks protocol command Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/inspector/InspectorDebuggerAgent.cpp
diff --git a/Source/core/inspector/InspectorDebuggerAgent.cpp b/Source/core/inspector/InspectorDebuggerAgent.cpp
index 44df24e310379c621a0dedf85e9387ccf0cb7522..51b687dc990529fe8a46e4dd62c862420cd42af7 100644
--- a/Source/core/inspector/InspectorDebuggerAgent.cpp
+++ b/Source/core/inspector/InspectorDebuggerAgent.cpp
@@ -49,7 +49,10 @@
#include "wtf/text/WTFString.h"
using WebCore::TypeBuilder::Array;
+using WebCore::TypeBuilder::Debugger::BreakpointId;
+using WebCore::TypeBuilder::Debugger::CallFrame;
using WebCore::TypeBuilder::Debugger::FunctionDetails;
+using WebCore::TypeBuilder::Debugger::Location;
using WebCore::TypeBuilder::Debugger::ScriptId;
using WebCore::TypeBuilder::Runtime::RemoteObject;
@@ -295,9 +298,9 @@ static bool matches(const String& url, const String& pattern, bool isRegex)
return url == pattern;
}
-void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* isAntiBreakpoint, TypeBuilder::Debugger::BreakpointId* outBreakpointId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations)
+void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* isAntiBreakpoint, BreakpointId* outBreakpointId, RefPtr<Array<Location> >& locations)
{
- locations = Array<TypeBuilder::Debugger::Location>::create();
+ locations = Array<Location>::create();
if (!optionalURL == !optionalURLRegex) {
*errorString = "Either url or urlRegex must be specified.";
return;
@@ -334,7 +337,7 @@ void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int li
for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
if (!matches(it->value.url, url, isRegex))
continue;
- RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(breakpointId, it->key, breakpoint, UserBreakpointSource);
+ RefPtr<Location> location = resolveBreakpoint(breakpointId, it->key, breakpoint, UserBreakpointSource);
if (location)
locations->addItem(location);
}
@@ -354,7 +357,7 @@ static bool parseLocation(ErrorString* errorString, PassRefPtr<JSONObject> locat
return true;
}
-void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<JSONObject>& location, const String* const optionalCondition, TypeBuilder::Debugger::BreakpointId* outBreakpointId, RefPtr<TypeBuilder::Debugger::Location>& actualLocation)
+void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<JSONObject>& location, const String* const optionalCondition, BreakpointId* outBreakpointId, RefPtr<Location>& actualLocation)
{
String scriptId;
int lineNumber;
@@ -427,7 +430,7 @@ void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const
resume(errorString);
}
-void InspectorDebuggerAgent::getStepInPositions(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::Location> >& positions)
+void InspectorDebuggerAgent::getStepInPositions(ErrorString* errorString, const String& callFrameId, RefPtr<Array<Location> >& positions)
{
if (!isPaused() || m_currentCallStack.isNull()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
@@ -442,7 +445,7 @@ void InspectorDebuggerAgent::getStepInPositions(ErrorString* errorString, const
injectedScript.getStepInPositions(errorString, m_currentCallStack, callFrameId, positions);
}
-void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& callFrames)
loislo 2013/11/20 01:39:18 please move these changes into another patch.
aandrey 2013/11/20 15:20:02 Extracted to https://codereview.chromium.org/77173
+void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString, RefPtr<Array<CallFrame> >& callFrames)
{
if (!assertPaused(errorString))
return;
@@ -539,7 +542,7 @@ ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPaus
return ScriptDebugListener::NoSkip;
}
-PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint& breakpoint, BreakpointSource source)
+PassRefPtr<Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint& breakpoint, BreakpointSource source)
{
ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
if (scriptIterator == m_scripts.end())
@@ -561,7 +564,7 @@ PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreak
debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).iterator;
debugServerBreakpointIdsIterator->value.append(debugServerBreakpointId);
- RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
+ RefPtr<Location> location = Location::create()
.setScriptId(scriptId)
.setLineNumber(actualLineNumber);
location->setColumnNumber(actualColumnNumber);
@@ -590,7 +593,7 @@ void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& s
*error = "No script for id: " + scriptId;
}
-void InspectorDebuggerAgent::setScriptSource(ErrorString* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result)
+void InspectorDebuggerAgent::setScriptSource(ErrorString* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<Array<CallFrame> >& newCallFrames, RefPtr<JSONObject>& result)
{
bool previewOnly = preview && *preview;
ScriptObject resultObject;
@@ -601,7 +604,7 @@ void InspectorDebuggerAgent::setScriptSource(ErrorString* error, RefPtr<TypeBuil
if (object)
result = object;
}
-void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result)
+void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<CallFrame> >& newCallFrames, RefPtr<JSONObject>& result)
{
if (!isPaused() || m_currentCallStack.isNull()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
@@ -627,7 +630,7 @@ void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& s
*error = "No script for id: " + scriptId;
}
-void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>& details)
+void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<FunctionDetails>& details)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(functionId);
if (injectedScript.hasNoValue()) {
@@ -654,11 +657,62 @@ void InspectorDebuggerAgent::cancelPauseOnNextStatement()
scriptDebugServer().setPauseOnNextStatement(false);
}
+void InspectorDebuggerAgent::requestAsyncCallFramesIfNeeded()
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ scriptDebugServer().requestAsyncCallFrames();
+}
+
+void InspectorDebuggerAgent::didRequestAsyncCallFrames(ScriptValue callFrames)
+{
+ m_asyncCallStackTracker.didRequestAsyncCallFrames(callFrames);
+}
+
+void InspectorDebuggerAgent::didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot)
+{
+ m_asyncCallStackTracker.didInstallTimer(timerId, singleShot);
+ requestAsyncCallFramesIfNeeded();
+}
+
+void InspectorDebuggerAgent::didRemoveTimer(ExecutionContext*, int timerId)
+{
+ m_asyncCallStackTracker.didRemoveTimer(timerId);
+}
+
+bool InspectorDebuggerAgent::willFireTimer(ExecutionContext*, int timerId)
+{
+ m_asyncCallStackTracker.willFireTimer(timerId);
+ return true;
+}
+
void InspectorDebuggerAgent::didFireTimer()
{
+ m_asyncCallStackTracker.didAsyncCall();
cancelPauseOnNextStatement();
}
+void InspectorDebuggerAgent::didRequestAnimationFrame(Document*, int callbackId)
+{
+ m_asyncCallStackTracker.didRequestAnimationFrame(callbackId);
+ requestAsyncCallFramesIfNeeded();
+}
+
+void InspectorDebuggerAgent::didCancelAnimationFrame(Document*, int callbackId)
+{
+ m_asyncCallStackTracker.didCancelAnimationFrame(callbackId);
+}
+
+bool InspectorDebuggerAgent::willFireAnimationFrame(Document*, int callbackId)
+{
+ m_asyncCallStackTracker.willFireAnimationFrame(callbackId);
+ return true;
+}
+
+void InspectorDebuggerAgent::didFireAnimationFrame()
+{
+ m_asyncCallStackTracker.didAsyncCall();
+}
+
void InspectorDebuggerAgent::didHandleEvent()
{
cancelPauseOnNextStatement();
@@ -754,7 +808,7 @@ void InspectorDebuggerAgent::setPauseOnExceptionsImpl(ErrorString* errorString,
m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, pauseState);
}
-void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
+void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
{
if (!isPaused() || m_currentCallStack.isNull()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
@@ -801,7 +855,7 @@ void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const Strin
*scriptId = scriptIdValue;
}
-void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
+void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
{
InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
if (injectedScript.hasNoValue()) {
@@ -883,6 +937,11 @@ void InspectorDebuggerAgent::skipStackFrames(ErrorString* errorString, const Str
m_cachedSkipStackRegExp = compiled.release();
}
+void InspectorDebuggerAgent::enableAsyncCallStacks(ErrorString*, int depth)
+{
+ m_asyncCallStackTracker.setMaxAsyncCallStackDepth(depth);
+}
+
void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText)
{
if (scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions) {
@@ -892,16 +951,28 @@ void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directive
}
}
-PassRefPtr<Array<TypeBuilder::Debugger::CallFrame> > InspectorDebuggerAgent::currentCallFrames()
+PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::currentCallFrames()
{
if (!m_pausedScriptState)
- return Array<TypeBuilder::Debugger::CallFrame>::create();
+ return Array<CallFrame>::create();
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState);
if (injectedScript.hasNoValue()) {
ASSERT_NOT_REACHED();
- return Array<TypeBuilder::Debugger::CallFrame>::create();
+ return Array<CallFrame>::create();
}
- return injectedScript.wrapCallFrames(m_currentCallStack);
+ RefPtr<Array<CallFrame> > result = injectedScript.wrapCallFrames(m_currentCallStack);
+ if (!result->length())
+ return result.release();
+ RefPtr<Array<CallFrame> > lastCallFrames = result;
+ AsyncCallStackIterator asyncCallStacks = m_asyncCallStackTracker.currentAsyncCallStack();
+ while (asyncCallStacks.hasNext()) {
+ RefPtr<CallFrame> last = CallFrame::runtimeCast(lastCallFrames->asArray()->get(lastCallFrames->length() - 1));
yurys 2013/11/20 01:23:43 Wouldn't lastCallFrames->get(lastCallFrames->lengt
aandrey 2013/11/20 15:20:02 Nope. TypeBuilder::Array::get is protected as well
+ lastCallFrames = injectedScript.wrapCallFrames(asyncCallStacks.next());
+ if (!lastCallFrames->length())
+ break;
+ last->setAsyncCallFrames(lastCallFrames);
+ }
+ return result.release();
}
String InspectorDebuggerAgent::sourceMapURLForScript(const Script& script)
@@ -963,7 +1034,7 @@ void InspectorDebuggerAgent::didParseSource(const String& scriptId, const Script
breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakpoint.lineNumber);
breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakpoint.columnNumber);
breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.condition);
- RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(it->key, scriptId, breakpoint, UserBreakpointSource);
+ RefPtr<Location> location = resolveBreakpoint(it->key, scriptId, breakpoint, UserBreakpointSource);
if (location)
m_frontend->breakpointResolved(it->key, location);
}
@@ -986,7 +1057,7 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValu
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
if (!injectedScript.hasNoValue()) {
m_breakReason = InspectorFrontend::Debugger::Reason::Exception;
- m_breakAuxData = injectedScript.wrapObject(exception, "backtrace")->openAccessors();
+ m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)->openAccessors();
// m_breakAuxData might be null after this.
}
}
@@ -1044,6 +1115,7 @@ void InspectorDebuggerAgent::clear()
m_currentCallStack = ScriptValue();
m_scripts.clear();
m_breakpointIdToDebugServerBreakpointIds.clear();
+ m_asyncCallStackTracker.clear();
m_continueToLocationBreakpointId = String();
clearBreakDetails();
m_javaScriptPauseScheduled = false;
@@ -1082,6 +1154,7 @@ void InspectorDebuggerAgent::reset()
{
m_scripts.clear();
m_breakpointIdToDebugServerBreakpointIds.clear();
+ m_asyncCallStackTracker.clear();
if (m_frontend)
m_frontend->globalObjectCleared();
}

Powered by Google App Engine
This is Rietveld 408576698