Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Web Inspector: Debugger should have an option for showing asynchronou…
…s call stacks https://bugs.webkit.org/show_bug.cgi?id=163230 <rdar://problem/28698683> Reviewed by Joseph Pecoraro. Source/JavaScriptCore: * inspector/ScriptCallFrame.cpp: (Inspector::ScriptCallFrame::isNative): Encapsulate check for native code source URL. * inspector/ScriptCallFrame.h: * inspector/ScriptCallStack.cpp: (Inspector::ScriptCallStack::firstNonNativeCallFrame): (Inspector::ScriptCallStack::buildInspectorArray): * inspector/ScriptCallStack.h: Replace use of Console::StackTrace with Array<Console::CallFrame>. * inspector/agents/InspectorDebuggerAgent.cpp: (Inspector::InspectorDebuggerAgent::disable): (Inspector::InspectorDebuggerAgent::setAsyncStackTraceDepth): Set number of async frames to store (including boundary frames). A value of zero disables recording of async call stacks. (Inspector::InspectorDebuggerAgent::buildAsyncStackTrace): Helper function for building a linked list StackTraces. (Inspector::InspectorDebuggerAgent::didScheduleAsyncCall): Store a call stack for the script that scheduled the async call. If the call repeats (e.g. setInterval), the starting reference count is set to 1. This ensures that dereffing after dispatch won't clear the stack. If another async call is currently being dispatched, increment the AsyncCallData reference count for that call. (Inspector::InspectorDebuggerAgent::didCancelAsyncCall): Decrement the reference count for the canceled call. (Inspector::InspectorDebuggerAgent::willDispatchAsyncCall): Set the identifier for the async callback currently being dispatched, so that if the debugger pauses during dispatch a stack trace can be associated with the pause location. If an async call is already being dispatched, which could be the case when a script schedules an async call in a nested runloop, do nothing. (Inspector::InspectorDebuggerAgent::didDispatchAsyncCall): Decrement the reference count for the canceled call. (Inspector::InspectorDebuggerAgent::didPause): If a stored stack trace exists for this location, convert to a protocol object and send to the frontend. (Inspector::InspectorDebuggerAgent::didClearGlobalObject): (Inspector::InspectorDebuggerAgent::clearAsyncStackTraceData): (Inspector::InspectorDebuggerAgent::refAsyncCallData): Increment AsyncCallData reference count. (Inspector::InspectorDebuggerAgent::derefAsyncCallData): Decrement AsyncCallData reference count. If zero, deref its parent (if it exists) and remove the AsyncCallData entry. * inspector/agents/InspectorDebuggerAgent.h: * inspector/protocol/Console.json: * inspector/protocol/Network.json: Replace use of Console.StackTrace with array of Console.CallFrame. * inspector/protocol/Debugger.json: New protocol command and event data. Source/WebCore: Test: inspector/debugger/async-stack-trace.html * inspector/InspectorInstrumentation.cpp: (WebCore::didScheduleAsyncCall): Helper function used by by instrumentation hooks. Informs the debugger agent that an asynchronous call was scheduled for the current script execution state. (WebCore::InspectorInstrumentation::didInstallTimerImpl): (WebCore::InspectorInstrumentation::didRemoveTimerImpl): (WebCore::InspectorInstrumentation::willFireTimerImpl): (WebCore::InspectorInstrumentation::didFireTimerImpl): Asynchronous stack trace plumbing for timers (setTimeout, setInterval). (WebCore::InspectorInstrumentation::didRequestAnimationFrameImpl): (WebCore::InspectorInstrumentation::didCancelAnimationFrameImpl): (WebCore::InspectorInstrumentation::willFireAnimationFrameImpl): (WebCore::InspectorInstrumentation::didFireAnimationFrameImpl): Asynchronous stack trace plumbing for requestAnimationFrame. Source/WebInspectorUI: * Localizations/en.lproj/localizedStrings.js: New string for generic async call stack boundary label: "(async)". * UserInterface/Controllers/DebuggerManager.js: Create async stack depth setting and set default depth. (WebInspector.DebuggerManager.prototype.get asyncStackTraceDepth): (WebInspector.DebuggerManager.prototype.set asyncStackTraceDepth): Make async stack depth setting accessible to the frontend. (WebInspector.DebuggerManager.prototype.initializeTarget): Set async stack depth value on the target. (WebInspector.DebuggerManager.prototype.debuggerDidPause): Plumbing for the async stack trace payload. * UserInterface/Models/ConsoleMessage.js: (WebInspector.ConsoleMessage): Updated for new StackTrace.fromPayload use. * UserInterface/Models/DebuggerData.js: (WebInspector.DebuggerData): (WebInspector.DebuggerData.prototype.get asyncStackTrace): (WebInspector.DebuggerData.prototype.updateForPause): (WebInspector.DebuggerData.prototype.updateForResume): More plumbing. * UserInterface/Models/StackTrace.js: Update frontend model for use as new protocol object Console.StackTrace, which was previously an alias for a simple array of Console.CallFrames. (WebInspector.StackTrace): (WebInspector.StackTrace.fromPayload): (WebInspector.StackTrace.fromString): (WebInspector.StackTrace.prototype.get topCallFrameIsBoundary): (WebInspector.StackTrace.prototype.get parentStackTrace): * UserInterface/Protocol/DebuggerObserver.js: (WebInspector.DebuggerObserver.prototype.paused): More plumbing. * UserInterface/Views/CallFrameTreeElement.css: (.tree-outline .item.call-frame.async-boundary): Use default cursor since boundary element is not selectable. (.tree-outline .item.call-frame.async-boundary .icon): (.tree-outline .item.call-frame.async-boundary::before,): (.tree-outline .item.call-frame.async-boundary::after): (.tree-outline .item.call-frame.async-boundary::before): Dimmed text and divider line styles for boundary element. * UserInterface/Views/CallFrameTreeElement.js: (WebInspector.CallFrameTreeElement): Add a flag denoting whether the call frame is an async call trace boundary, and set styles accordingly. * UserInterface/Views/DebuggerSidebarPanel.js: Set async stack trace depth, if supported. (WebInspector.DebuggerSidebarPanel.prototype._updateSingleThreadCallStacks): Add call frames for async stack traces to the call stack TreeOutline. (WebInspector.DebuggerSidebarPanel.prototype._treeSelectionDidChange): Ensure that async call frames cannot become the active call frame. * UserInterface/Views/Variables.css: (:root): Add --text-color-gray-medium, for dimmed text in async boundary element. LayoutTests: Add basic tests for async stack trace data included in Debugger.paused, and check that requestAnimationFrame, setTimeout, and setInterval are supported. * inspector/debugger/async-stack-trace-expected.txt: Added. * inspector/debugger/async-stack-trace.html: Added. Canonical link: https://commits.webkit.org/182752@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209062 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information