<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[173731] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/173731">173731</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-09-18 12:47:55 -0700 (Thu, 18 Sep 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Should be able to attach a debugger to a JSContext before anything is executed
https://bugs.webkit.org/show_bug.cgi?id=136893

Patch by Joseph Pecoraro &lt;pecoraro@apple.com&gt; on 2014-09-18
Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Adds new remote inspector protocol handling for automatic inspection.
Debuggers can signal they have enabled automatic inspection, and
when debuggables are created the current application will pause to
see if the debugger will inspect or decline to inspect the debuggable.

* inspector/remote/RemoteInspectorConstants.h:
* inspector/remote/RemoteInspector.h:
* inspector/remote/RemoteInspector.mm:
(Inspector::globalAutomaticInspectionState):
(Inspector::RemoteInspector::RemoteInspector):
(Inspector::RemoteInspector::start):
When first starting, check the global &quot;is there an auto-inspect&quot; debugger state.
This is necessary so that the current application knows if it should pause or
not when a debuggable is created, even without having connected to webinspectord yet.

(Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate):
When a debuggable has enabled remote inspection, take this path to propose
it as an automatic inspection candidate if there is an auto-inspect debugger.

(Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage):
Send the automatic inspection candidate message.

(Inspector::RemoteInspector::receivedSetupMessage):
(Inspector::RemoteInspector::setupFailed):
(Inspector::RemoteInspector::setupSucceeded):
After attempting to open an inspector, unpause if it was for the
automatic inspection candidate.

(Inspector::RemoteInspector::waitingForAutomaticInspection):
When running a nested runloop, check if we should remain paused.

(Inspector::RemoteInspector::setupXPCConnectionIfNeeded):
If by the time we connect to webinspectord we have a candidate, then
immediately send the candidate message.

(Inspector::RemoteInspector::stopInternal):
(Inspector::RemoteInspector::xpcConnectionFailed):
In error cases, clear our state.

(Inspector::RemoteInspector::xpcConnectionReceivedMessage):
(Inspector::RemoteInspector::receivedAutomaticInspectionConfigurationMessage):
(Inspector::RemoteInspector::receivedAutomaticInspectionRejectMessage):
Update state when receiving new messages.

* inspector/remote/RemoteInspectorDebuggable.h:
* inspector/remote/RemoteInspectorDebuggable.cpp:
(Inspector::RemoteInspectorDebuggable::setRemoteDebuggingAllowed):
Special case when a debuggable is newly allowed to be debuggable.

(Inspector::RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection):
Run a nested run loop while this is an automatic inspection candidate.

* inspector/JSGlobalObjectInspectorController.h:
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
(Inspector::JSGlobalObjectInspectorController::connectFrontend):
When the inspector starts via automatic inspection automatically pause.
We plan on removing this condition by having the frontend signal to the
backend when it is completely initialized.

* inspector/remote/RemoteInspectorDebuggableConnection.h:
* inspector/remote/RemoteInspectorDebuggableConnection.mm:
(Inspector::RemoteInspectorDebuggableConnection::setup):
Pass on the flag of whether or not this was automatic inspection.

* runtime/JSGlobalObjectDebuggable.h:
* runtime/JSGlobalObjectDebuggable.cpp:
(JSC::JSGlobalObjectDebuggable::connect):
(JSC::JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection):
When pausing in a JSGlobalObject we need to release the API lock.

Source/WebCore:

Automatic inspection is currently disabled for web pages.
This just updates the interfaces that changed.

* WebCore.exp.in:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::connectFrontend):
(WebCore::InspectorController::show):
* inspector/InspectorController.h:
* page/PageDebuggable.cpp:
(WebCore::PageDebuggable::connect):
* page/PageDebuggable.h:
* testing/Internals.cpp:
(WebCore::Internals::openDummyInspectorFrontend):

Source/WTF:

Currently automatic inspection only happens in processes that have a
debugger attached. That condition may change in the future, but this
function can stand on its own in WTF. It may be useful in the future
to perhaps continue though ASSERTs if you have a debugger attached.

* wtf/Assertions.cpp:
* wtf/Assertions.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorh">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectormm">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.mm</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorConstantsh">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorConstants.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggablecpp">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableh">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableConnectionh">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableConnectionmm">trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggablecpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggableh">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfAssertionscpp">trunk/Source/WTF/wtf/Assertions.cpp</a></li>
<li><a href="#trunkSourceWTFwtfAssertionsh">trunk/Source/WTF/wtf/Assertions.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllercpp">trunk/Source/WebCore/inspector/InspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllerh">trunk/Source/WebCore/inspector/InspectorController.h</a></li>
<li><a href="#trunkSourceWebCorepagePageDebuggablecpp">trunk/Source/WebCore/page/PageDebuggable.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageDebuggableh">trunk/Source/WebCore/page/PageDebuggable.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -1,3 +1,82 @@
</span><ins>+2014-09-18  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Should be able to attach a debugger to a JSContext before anything is executed
+        https://bugs.webkit.org/show_bug.cgi?id=136893
+
+        Reviewed by Timothy Hatcher.
+
+        Adds new remote inspector protocol handling for automatic inspection.
+        Debuggers can signal they have enabled automatic inspection, and
+        when debuggables are created the current application will pause to
+        see if the debugger will inspect or decline to inspect the debuggable.
+
+        * inspector/remote/RemoteInspectorConstants.h:
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::globalAutomaticInspectionState):
+        (Inspector::RemoteInspector::RemoteInspector):
+        (Inspector::RemoteInspector::start):
+        When first starting, check the global &quot;is there an auto-inspect&quot; debugger state.
+        This is necessary so that the current application knows if it should pause or
+        not when a debuggable is created, even without having connected to webinspectord yet.
+
+        (Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate):
+        When a debuggable has enabled remote inspection, take this path to propose
+        it as an automatic inspection candidate if there is an auto-inspect debugger.
+
+        (Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage):
+        Send the automatic inspection candidate message.
+
+        (Inspector::RemoteInspector::receivedSetupMessage):
+        (Inspector::RemoteInspector::setupFailed):
+        (Inspector::RemoteInspector::setupSucceeded):
+        After attempting to open an inspector, unpause if it was for the
+        automatic inspection candidate.
+
+        (Inspector::RemoteInspector::waitingForAutomaticInspection):
+        When running a nested runloop, check if we should remain paused.
+
+        (Inspector::RemoteInspector::setupXPCConnectionIfNeeded):
+        If by the time we connect to webinspectord we have a candidate, then
+        immediately send the candidate message.
+
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::xpcConnectionFailed):
+        In error cases, clear our state.
+
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        (Inspector::RemoteInspector::receivedAutomaticInspectionConfigurationMessage):
+        (Inspector::RemoteInspector::receivedAutomaticInspectionRejectMessage):
+        Update state when receiving new messages.
+
+
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::setRemoteDebuggingAllowed):
+        Special case when a debuggable is newly allowed to be debuggable.
+
+        (Inspector::RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection):
+        Run a nested run loop while this is an automatic inspection candidate.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        When the inspector starts via automatic inspection automatically pause.
+        We plan on removing this condition by having the frontend signal to the
+        backend when it is completely initialized.
+        
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        Pass on the flag of whether or not this was automatic inspection.
+
+        * runtime/JSGlobalObjectDebuggable.h:
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::connect):
+        (JSC::JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection):
+        When pausing in a JSGlobalObject we need to release the API lock.
+
</ins><span class="cx"> 2014-09-18  Eva Balazsfalvi  &lt;evab.u-szeged@partner.samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix &quot;Tools/Scripts/build-webkit --efl --no-inspector&quot; build
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx">     auto consoleAgent = std::make_unique&lt;JSGlobalObjectConsoleAgent&gt;(m_injectedScriptManager.get());
</span><span class="cx">     auto debuggerAgent = std::make_unique&lt;JSGlobalObjectDebuggerAgent&gt;(m_injectedScriptManager.get(), m_globalObject, consoleAgent.get());
</span><span class="cx"> 
</span><ins>+    m_debuggerAgent = debuggerAgent.get();
</ins><span class="cx">     m_consoleAgent = consoleAgent.get();
</span><span class="cx">     m_consoleClient = std::make_unique&lt;JSGlobalObjectConsoleClient&gt;(m_consoleAgent);
</span><span class="cx"> 
</span><span class="lines">@@ -84,7 +85,7 @@
</span><span class="cx">     m_injectedScriptManager-&gt;disconnect();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSGlobalObjectInspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
</del><ins>+void JSGlobalObjectInspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel, bool isAutomaticInspection)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_inspectorFrontendChannel);
</span><span class="cx">     ASSERT(!m_inspectorBackendDispatcher);
</span><span class="lines">@@ -93,6 +94,15 @@
</span><span class="cx">     m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel);
</span><span class="cx"> 
</span><span class="cx">     m_agents.didCreateFrontendAndBackend(frontendChannel, m_inspectorBackendDispatcher.get());
</span><ins>+
+    if (isAutomaticInspection) {
+        // FIXME: We should not always pause for automatic inspection.
+        // Currently if we don't automatically pause, then we may miss a breakpoint, since breakpoints
+        // come from the frontend and might be received after some evaluateScript message. We should
+        // have the frontend signal the backend when its setup messages are complete.
+        m_debuggerAgent-&gt;enable(nullptr);
+        m_debuggerAgent-&gt;pause(nullptr);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectInspectorController::disconnectFrontend(InspectorDisconnectReason reason)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> class InspectorConsoleAgent;
</span><span class="cx"> class InspectorBackendDispatcher;
</span><span class="cx"> class InspectorConsoleAgent;
</span><ins>+class InspectorDebuggerAgent;
</ins><span class="cx"> class InspectorFrontendChannel;
</span><span class="cx"> class JSGlobalObjectConsoleClient;
</span><span class="cx"> class ScriptCallStack;
</span><span class="lines">@@ -58,7 +59,7 @@
</span><span class="cx">     JSGlobalObjectInspectorController(JSC::JSGlobalObject&amp;);
</span><span class="cx">     ~JSGlobalObjectInspectorController();
</span><span class="cx"> 
</span><del>-    void connectFrontend(InspectorFrontendChannel*);
</del><ins>+    void connectFrontend(InspectorFrontendChannel*, bool isAutomaticInspection);
</ins><span class="cx">     void disconnectFrontend(InspectorDisconnectReason reason);
</span><span class="cx">     void dispatchMessageFromFrontend(const String&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -85,6 +86,7 @@
</span><span class="cx">     std::unique_ptr&lt;InjectedScriptManager&gt; m_injectedScriptManager;
</span><span class="cx">     std::unique_ptr&lt;JSGlobalObjectConsoleClient&gt; m_consoleClient;
</span><span class="cx">     InspectorConsoleAgent* m_consoleAgent;
</span><ins>+    InspectorDebuggerAgent* m_debuggerAgent;
</ins><span class="cx">     InspectorAgentRegistry m_agents;
</span><span class="cx">     InspectorFrontendChannel* m_inspectorFrontendChannel;
</span><span class="cx">     RefPtr&lt;InspectorBackendDispatcher&gt; m_inspectorBackendDispatcher;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -52,8 +52,11 @@
</span><span class="cx">     void registerDebuggable(RemoteInspectorDebuggable*);
</span><span class="cx">     void unregisterDebuggable(RemoteInspectorDebuggable*);
</span><span class="cx">     void updateDebuggable(RemoteInspectorDebuggable*);
</span><ins>+    void updateDebuggableAutomaticInspectCandidate(RemoteInspectorDebuggable*);
</ins><span class="cx">     void sendMessageToRemoteFrontend(unsigned identifier, const String&amp; message);
</span><span class="cx">     void setupFailed(unsigned identifier);
</span><ins>+    void setupSucceeded(unsigned identifier);
+    bool waitingForAutomaticInspection(unsigned identifier);
</ins><span class="cx"> 
</span><span class="cx">     bool enabled() const { return m_enabled; }
</span><span class="cx">     bool hasActiveDebugSession() const { return m_hasActiveDebugSession; }
</span><span class="lines">@@ -83,6 +86,8 @@
</span><span class="cx"> 
</span><span class="cx">     void updateHasActiveDebugSession();
</span><span class="cx"> 
</span><ins>+    void sendAutomaticInspectionCandidateMessage();
+
</ins><span class="cx">     virtual void xpcConnectionReceivedMessage(RemoteInspectorXPCConnection*, NSString *messageName, NSDictionary *userInfo) override;
</span><span class="cx">     virtual void xpcConnectionFailed(RemoteInspectorXPCConnection*) override;
</span><span class="cx">     virtual void xpcConnectionUnhandledMessage(RemoteInspectorXPCConnection*, xpc_object_t) override;
</span><span class="lines">@@ -94,6 +99,8 @@
</span><span class="cx">     void receivedIndicateMessage(NSDictionary *userInfo);
</span><span class="cx">     void receivedProxyApplicationSetupMessage(NSDictionary *userInfo);
</span><span class="cx">     void receivedConnectionDiedMessage(NSDictionary *userInfo);
</span><ins>+    void receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo);
+    void receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo);
</ins><span class="cx"> 
</span><span class="cx">     static bool startEnabled;
</span><span class="cx"> 
</span><span class="lines">@@ -117,6 +124,9 @@
</span><span class="cx">     pid_t m_parentProcessIdentifier;
</span><span class="cx">     RetainPtr&lt;CFDataRef&gt; m_parentProcessAuditData;
</span><span class="cx">     bool m_shouldSendParentProcessInformation;
</span><ins>+    bool m_automaticInspectionEnabled;
+    bool m_automaticInspectionPaused;
+    unsigned m_automaticInspectionCandidateIdentifier;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectormm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.mm (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.mm        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.mm        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -68,6 +68,17 @@
</span><span class="cx">     return sandbox_check(getpid(), &quot;mach-lookup&quot;, SANDBOX_FILTER_GLOBAL_NAME, WIRXPCMachPortName) == 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool globalAutomaticInspectionState()
+{
+    int token = 0;
+    if (notify_register_check(WIRAutomaticInspectionEnabledState, &amp;token) != NOTIFY_STATUS_OK)
+        return false;
+
+    uint64_t automaticInspectionEnabled = 0;
+    notify_get_state(token, &amp;automaticInspectionEnabled);
+    return automaticInspectionEnabled == 1;
+}
+
</ins><span class="cx"> static void dispatchAsyncOnQueueSafeForAnyDebuggable(void (^block)())
</span><span class="cx"> {
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -112,6 +123,9 @@
</span><span class="cx">     , m_pushScheduled(false)
</span><span class="cx">     , m_parentProcessIdentifier(0)
</span><span class="cx">     , m_shouldSendParentProcessInformation(false)
</span><ins>+    , m_automaticInspectionEnabled(false)
+    , m_automaticInspectionPaused(false)
+    , m_automaticInspectionCandidateIdentifier(0)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -170,6 +184,74 @@
</span><span class="cx">     pushListingSoon();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RemoteInspector::updateDebuggableAutomaticInspectCandidate(RemoteInspectorDebuggable* debuggable)
+{
+    {
+        std::lock_guard&lt;std::mutex&gt; lock(m_mutex);
+
+        unsigned identifier = debuggable-&gt;identifier();
+        if (!identifier)
+            return;
+
+        auto result = m_debuggableMap.set(identifier, std::make_pair(debuggable, debuggable-&gt;info()));
+        ASSERT_UNUSED(result, !result.isNewEntry);
+
+        // Don't allow automatic inspection unless there is a debugger or we are stopped.
+        if (!WTFIsDebuggerAttached() || !m_automaticInspectionEnabled || !m_enabled) {
+            pushListingSoon();
+            return;
+        }
+
+        // FIXME: We should handle multiple debuggables trying to pause at the same time on different threads.
+        // To make this work we will need to change m_automaticInspectionCandidateIdentifier to be a per-thread value.
+        // Multiple attempts on the same thread should not be possible because our nested run loop is in a special RWI mode.
+        if (m_automaticInspectionPaused) {
+            LOG_ERROR(&quot;Skipping Automatic Inspection Candidate with pageId(%u) because we are already paused waiting for pageId(%u)&quot;, identifier, m_automaticInspectionCandidateIdentifier);
+            pushListingSoon();
+            return;
+        }
+
+        m_automaticInspectionPaused = true;
+        m_automaticInspectionCandidateIdentifier = identifier;
+
+        // If we are pausing before we have connected to webinspectord the candidate message will be sent as soon as the connection is established.
+        if (m_xpcConnection) {
+            pushListingNow();
+            sendAutomaticInspectionCandidateMessage();
+        }
+
+        // In case debuggers fail to respond, or we cannot connect to webinspectord, automatically continue after a short period of time.
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+            std::lock_guard&lt;std::mutex&gt; lock(m_mutex);
+            if (m_automaticInspectionCandidateIdentifier == identifier) {
+                LOG_ERROR(&quot;Skipping Automatic Inspection Candidate with pageId(%u) because we failed to receive a response in time.&quot;, m_automaticInspectionCandidateIdentifier);
+                m_automaticInspectionPaused = false;
+            }
+        });
+    }
+
+    debuggable-&gt;pauseWaitingForAutomaticInspection();
+
+    {
+        std::lock_guard&lt;std::mutex&gt; lock(m_mutex);
+
+        ASSERT(m_automaticInspectionCandidateIdentifier);
+        m_automaticInspectionCandidateIdentifier = 0;
+    }
+}
+
+void RemoteInspector::sendAutomaticInspectionCandidateMessage()
+{
+    ASSERT(m_enabled);
+    ASSERT(m_automaticInspectionEnabled);
+    ASSERT(m_automaticInspectionPaused);
+    ASSERT(m_automaticInspectionCandidateIdentifier);
+    ASSERT(m_xpcConnection);
+
+    NSDictionary *details = @{WIRPageIdentifierKey: @(m_automaticInspectionCandidateIdentifier)};
+    m_xpcConnection-&gt;sendMessage(WIRAutomaticInspectionCandidateMessage, details);
+}
+
</ins><span class="cx"> void RemoteInspector::sendMessageToRemoteFrontend(unsigned identifier, const String&amp; message)
</span><span class="cx"> {
</span><span class="cx">     std::lock_guard&lt;std::mutex&gt; lock(m_mutex);
</span><span class="lines">@@ -198,9 +280,26 @@
</span><span class="cx"> 
</span><span class="cx">     updateHasActiveDebugSession();
</span><span class="cx"> 
</span><ins>+    if (identifier == m_automaticInspectionCandidateIdentifier)
+        m_automaticInspectionPaused = false;
+
</ins><span class="cx">     pushListingSoon();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RemoteInspector::setupSucceeded(unsigned identifier)
+{
+    std::lock_guard&lt;std::mutex&gt; lock(m_mutex);
+
+    if (identifier == m_automaticInspectionCandidateIdentifier)
+        m_automaticInspectionPaused = false;
+}
+
+bool RemoteInspector::waitingForAutomaticInspection(unsigned)
+{
+    // We don't take the lock to check this because we assume it will be checked repeatedly.
+    return m_automaticInspectionPaused;
+}
+
</ins><span class="cx"> void RemoteInspector::start()
</span><span class="cx"> {
</span><span class="cx">     std::lock_guard&lt;std::mutex&gt; lock(m_mutex);
</span><span class="lines">@@ -210,6 +309,12 @@
</span><span class="cx"> 
</span><span class="cx">     m_enabled = true;
</span><span class="cx"> 
</span><ins>+    // Load the initial automatic inspection state when first started, so we know it before we have even connected to webinspectord.
+    static dispatch_once_t once;
+    dispatch_once(&amp;once, ^{
+        m_automaticInspectionEnabled = globalAutomaticInspectionState();
+    });
+
</ins><span class="cx">     notify_register_dispatch(WIRServiceAvailableNotification, &amp;m_notifyToken, m_xpcQueue, ^(int) {
</span><span class="cx">         RemoteInspector::shared().setupXPCConnectionIfNeeded();
</span><span class="cx">     });
</span><span class="lines">@@ -239,6 +344,8 @@
</span><span class="cx"> 
</span><span class="cx">     updateHasActiveDebugSession();
</span><span class="cx"> 
</span><ins>+    m_automaticInspectionPaused = false;
+
</ins><span class="cx">     if (m_xpcConnection) {
</span><span class="cx">         switch (source) {
</span><span class="cx">         case StopSource::API:
</span><span class="lines">@@ -270,7 +377,12 @@
</span><span class="cx">     m_xpcConnection-&gt;sendMessage(@&quot;syn&quot;, nil); // Send a simple message to initialize the XPC connection.
</span><span class="cx">     xpc_release(connection);
</span><span class="cx"> 
</span><del>-    pushListingSoon();
</del><ins>+    if (m_automaticInspectionCandidateIdentifier) {
+        // We already have a debuggable waiting to be automatically inspected.
+        pushListingNow();
+        sendAutomaticInspectionCandidateMessage();
+    } else
+        pushListingSoon();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #pragma mark - Proxy Application Information
</span><span class="lines">@@ -314,6 +426,10 @@
</span><span class="cx">         receivedProxyApplicationSetupMessage(userInfo);
</span><span class="cx">     else if ([messageName isEqualToString:WIRConnectionDiedMessage])
</span><span class="cx">         receivedConnectionDiedMessage(userInfo);
</span><ins>+    else if ([messageName isEqualToString:WIRAutomaticInspectionConfigurationMessage])
+        receivedAutomaticInspectionConfigurationMessage(userInfo);
+    else if ([messageName isEqualToString:WIRAutomaticInspectionRejectMessage])
+        receivedAutomaticInspectionRejectMessage(userInfo);
</ins><span class="cx">     else
</span><span class="cx">         NSLog(@&quot;Unrecognized RemoteInspector XPC Message: %@&quot;, messageName);
</span><span class="cx"> }
</span><span class="lines">@@ -334,6 +450,8 @@
</span><span class="cx"> 
</span><span class="cx">     updateHasActiveDebugSession();
</span><span class="cx"> 
</span><ins>+    m_automaticInspectionPaused = false;
+
</ins><span class="cx">     // The connection will close itself.
</span><span class="cx">     m_xpcConnection = nullptr;
</span><span class="cx"> }
</span><span class="lines">@@ -433,6 +551,7 @@
</span><span class="cx">     // Legacy iOS WebKit 1 had a notification. This will need to be smarter with WebKit2.
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> #pragma mark - Received XPC Messages
</span><span class="cx"> 
</span><span class="cx"> void RemoteInspector::receivedSetupMessage(NSDictionary *userInfo)
</span><span class="lines">@@ -461,7 +580,8 @@
</span><span class="cx">     RemoteInspectorDebuggable* debuggable = it-&gt;value.first;
</span><span class="cx">     RemoteInspectorDebuggableInfo debuggableInfo = it-&gt;value.second;
</span><span class="cx">     RefPtr&lt;RemoteInspectorDebuggableConnection&gt; connection = adoptRef(new RemoteInspectorDebuggableConnection(debuggable, connectionIdentifier, sender, debuggableInfo.type));
</span><del>-    if (!connection-&gt;setup()) {
</del><ins>+    bool isAutomaticInspection = m_automaticInspectionCandidateIdentifier == debuggable-&gt;identifier();
+    if (!connection-&gt;setup(isAutomaticInspection)) {
</ins><span class="cx">         connection-&gt;close();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -593,6 +713,23 @@
</span><span class="cx">     updateHasActiveDebugSession();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RemoteInspector::receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo)
+{
+    m_automaticInspectionEnabled = [[userInfo objectForKey:WIRAutomaticInspectionEnabledKey] boolValue];
+
+    if (!m_automaticInspectionEnabled &amp;&amp; m_automaticInspectionPaused)
+        m_automaticInspectionPaused = false;
+}
+
+void RemoteInspector::receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo)
+{
+    unsigned rejectionIdentifier = [[userInfo objectForKey:WIRPageIdentifierKey] unsignedIntValue];
+
+    ASSERT(rejectionIdentifier == m_automaticInspectionCandidateIdentifier);
+    if (rejectionIdentifier == m_automaticInspectionCandidateIdentifier)
+        m_automaticInspectionPaused = false;
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(REMOTE_INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorConstantsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorConstants.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorConstants.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorConstants.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -37,12 +37,14 @@
</span><span class="cx"> #define WIRServiceAvailabilityCheckNotification &quot;com.apple.webinspectord.availability_check&quot;
</span><span class="cx"> #define WIRServiceEnabledNotification           &quot;com.apple.webinspectord.enabled&quot;
</span><span class="cx"> #define WIRServiceDisabledNotification          &quot;com.apple.webinspectord.disabled&quot;
</span><ins>+#define WIRAutomaticInspectionEnabledState      &quot;com.apple.webinspectord.automatic_inspection_enabled&quot;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> #define WIRApplicationIdentifierKey             @&quot;WIRApplicationIdentifierKey&quot;
</span><span class="cx"> #define WIRApplicationBundleIdentifierKey       @&quot;WIRApplicationBundleIdentifierKey&quot;
</span><span class="cx"> #define WIRApplicationNameKey                   @&quot;WIRApplicationNameKey&quot;
</span><span class="cx"> #define WIRIsApplicationProxyKey                @&quot;WIRIsApplicationProxyKey&quot;
</span><ins>+#define WIRIsApplicationActiveKey               @&quot;WIRIsApplicationActiveKey&quot;
</ins><span class="cx"> #define WIRHostApplicationIdentifierKey         @&quot;WIRHostApplicationIdentifierKey&quot;
</span><span class="cx"> #define WIRHostApplicationNameKey               @&quot;WIRHostApplicationNameKey&quot;
</span><span class="cx"> #define WIRConnectionIdentifierKey              @&quot;WIRConnectionIdentifierKey&quot;
</span><span class="lines">@@ -71,6 +73,12 @@
</span><span class="cx"> #define WIRTypeJavaScript                       @&quot;WIRTypeJavaScript&quot;
</span><span class="cx"> #define WIRTypeWeb                              @&quot;WIRTypeWeb&quot;
</span><span class="cx"> 
</span><ins>+#define WIRAutomaticInspectionEnabledKey           @&quot;WIRAutomaticInspectionEnabledKey&quot;
+#define WIRAutomaticInspectionSessionIdentifierKey @&quot;WIRAutomaticInspectionSessionIdentifierKey&quot;
+#define WIRAutomaticInspectionConfigurationMessage @&quot;WIRAutomaticInspectionConfigurationMessage&quot;
+#define WIRAutomaticInspectionRejectMessage        @&quot;WIRAutomaticInspectionRejectMessage&quot;
+#define WIRAutomaticInspectionCandidateMessage     @&quot;WIRAutomaticInspectionCandidateMessage&quot;
+
</ins><span class="cx"> // These definitions are shared with a Simulator webinspectord and
</span><span class="cx"> // OS X process communicating with it.
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(REMOTE_INSPECTOR)
</span><span class="cx"> 
</span><ins>+#include &quot;EventLoop.h&quot;
</ins><span class="cx"> #include &quot;InspectorFrontendChannel.h&quot;
</span><span class="cx"> #include &quot;RemoteInspector.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -61,7 +62,10 @@
</span><span class="cx"> 
</span><span class="cx">     m_allowed = allowed;
</span><span class="cx"> 
</span><del>-    update();
</del><ins>+    if (m_allowed &amp;&amp; automaticInspectionAllowed())
+        RemoteInspector::shared().updateDebuggableAutomaticInspectCandidate(this);
+    else
+        RemoteInspector::shared().updateDebuggable(this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RemoteInspectorDebuggableInfo RemoteInspectorDebuggable::info() const
</span><span class="lines">@@ -76,6 +80,17 @@
</span><span class="cx">     return info;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection()
+{
+    ASSERT(m_identifier);
+    ASSERT(m_allowed);
+    ASSERT(automaticInspectionAllowed());
+
+    EventLoop loop;
+    while (RemoteInspector::shared().waitingForAutomaticInspection(identifier()) &amp;&amp; !loop.ended())
+        loop.cycle();
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(REMOTE_INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggable.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -62,11 +62,14 @@
</span><span class="cx">     virtual String url() const { return String(); } // Web
</span><span class="cx">     virtual bool hasLocalDebugger() const = 0;
</span><span class="cx"> 
</span><del>-    virtual void connect(InspectorFrontendChannel*) = 0;
</del><ins>+    virtual void connect(InspectorFrontendChannel*, bool isAutomaticInspection) = 0;
</ins><span class="cx">     virtual void disconnect() = 0;
</span><span class="cx">     virtual void dispatchMessageFromRemoteFrontend(const String&amp; message) = 0;
</span><span class="cx">     virtual void setIndicating(bool) { } // Default is to do nothing.
</span><span class="cx"> 
</span><ins>+    virtual bool automaticInspectionAllowed() const { return false; }
+    virtual void pauseWaitingForAutomaticInspection();
+
</ins><span class="cx"> private:
</span><span class="cx">     unsigned m_identifier;
</span><span class="cx">     bool m_allowed;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx">     NSString *connectionIdentifier() const;
</span><span class="cx">     unsigned identifier() const { return m_identifier; }
</span><span class="cx"> 
</span><del>-    bool setup();
</del><ins>+    bool setup(bool isAutomaticInspection);
</ins><span class="cx"> 
</span><span class="cx">     void close();
</span><span class="cx">     void closeFromDebuggable();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorremoteRemoteInspectorDebuggableConnectionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/inspector/remote/RemoteInspectorDebuggableConnection.mm        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx">     RemoteInspectorQueueTaskOnGlobalQueue(block);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RemoteInspectorDebuggableConnection::setup()
</del><ins>+bool RemoteInspectorDebuggableConnection::setup(bool isAutomaticInspection)
</ins><span class="cx"> {
</span><span class="cx">     std::lock_guard&lt;std::mutex&gt; lock(m_debuggableMutex);
</span><span class="cx"> 
</span><span class="lines">@@ -164,8 +164,9 @@
</span><span class="cx">                 RemoteInspector::shared().setupFailed(identifier());
</span><span class="cx">                 m_debuggable = nullptr;
</span><span class="cx">             } else {
</span><del>-                m_debuggable-&gt;connect(this);
</del><ins>+                m_debuggable-&gt;connect(this, isAutomaticInspection);
</ins><span class="cx">                 m_connected = true;
</span><ins>+                RemoteInspector::shared().setupSucceeded(identifier());
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         deref();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(REMOTE_INSPECTOR)
</span><span class="cx"> 
</span><ins>+#include &quot;JSLock.h&quot;
</ins><span class="cx"> #include &quot;InspectorAgentBase.h&quot;
</span><span class="cx"> #include &quot;InspectorFrontendChannel.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="lines">@@ -48,11 +49,11 @@
</span><span class="cx">     return name.isEmpty() ? ASCIILiteral(&quot;JSContext&quot;) : name;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSGlobalObjectDebuggable::connect(InspectorFrontendChannel* frontendChannel)
</del><ins>+void JSGlobalObjectDebuggable::connect(InspectorFrontendChannel* frontendChannel, bool automaticInspection)
</ins><span class="cx"> {
</span><span class="cx">     JSLockHolder locker(&amp;m_globalObject.vm());
</span><span class="cx"> 
</span><del>-    m_globalObject.inspectorController().connectFrontend(frontendChannel);
</del><ins>+    m_globalObject.inspectorController().connectFrontend(frontendChannel, automaticInspection);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSGlobalObjectDebuggable::disconnect()
</span><span class="lines">@@ -69,6 +70,12 @@
</span><span class="cx">     m_globalObject.inspectorController().dispatchMessageFromFrontend(message);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection()
+{
+    JSC::JSLock::DropAllLocks dropAllLocks(&amp;m_globalObject.vm());
+    RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(REMOTE_INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectDebuggableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -51,10 +51,13 @@
</span><span class="cx">     virtual String name() const override;
</span><span class="cx">     virtual bool hasLocalDebugger() const override { return false; }
</span><span class="cx"> 
</span><del>-    virtual void connect(Inspector::InspectorFrontendChannel*) override;
</del><ins>+    virtual void connect(Inspector::InspectorFrontendChannel*, bool automaticInspection) override;
</ins><span class="cx">     virtual void disconnect() override;
</span><span class="cx">     virtual void dispatchMessageFromRemoteFrontend(const String&amp; message) override;
</span><span class="cx"> 
</span><ins>+    virtual bool automaticInspectionAllowed() const override { return true; }
+    virtual void pauseWaitingForAutomaticInspection() override;
+
</ins><span class="cx"> private:
</span><span class="cx">     JSGlobalObject&amp; m_globalObject;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WTF/ChangeLog        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2014-09-18  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Should be able to attach a debugger to a JSContext before anything is executed
+        https://bugs.webkit.org/show_bug.cgi?id=136893
+
+        Reviewed by Timothy Hatcher.
+
+        Currently automatic inspection only happens in processes that have a
+        debugger attached. That condition may change in the future, but this
+        function can stand on its own in WTF. It may be useful in the future
+        to perhaps continue though ASSERTs if you have a debugger attached.
+
+        * wtf/Assertions.cpp:
+        * wtf/Assertions.h:
+
</ins><span class="cx"> 2014-09-18  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         GMainLoopSource is exposed to race conditions
</span></span></pre></div>
<a id="trunkSourceWTFwtfAssertionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Assertions.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Assertions.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WTF/wtf/Assertions.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -63,6 +63,11 @@
</span><span class="cx"> #include &lt;windows.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if OS(DARWIN)
+#include &lt;sys/sysctl.h&gt;
+#include &lt;unistd.h&gt;
+#endif
+
</ins><span class="cx"> #if OS(DARWIN) || (OS(LINUX) &amp;&amp; !defined(__UCLIBC__))
</span><span class="cx"> #include &lt;cxxabi.h&gt;
</span><span class="cx"> #include &lt;dlfcn.h&gt;
</span><span class="lines">@@ -385,6 +390,20 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WTFIsDebuggerAttached()
+{
+#if OS(DARWIN)
+    struct kinfo_proc info;
+    int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
+    size_t size = sizeof(info);
+    if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &amp;info, &amp;size, nullptr, 0) != 0)
+        return false;
+    return (info.kp_proc.p_flag &amp; P_TRACED) != 0;
+#else
+    return false;
+#endif
+}
+
</ins><span class="cx"> void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
</span><span class="cx"> {
</span><span class="cx">     va_list args;
</span></span></pre></div>
<a id="trunkSourceWTFwtfAssertionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Assertions.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Assertions.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WTF/wtf/Assertions.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &lt;inttypes.h&gt;
</span><span class="cx"> #include &lt;stdarg.h&gt;
</span><ins>+#include &lt;stdbool.h&gt;
</ins><span class="cx"> #include &lt;stddef.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #ifdef NDEBUG
</span><span class="lines">@@ -145,6 +146,8 @@
</span><span class="cx"> WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
</span><span class="cx"> WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
</span><span class="cx"> 
</span><ins>+WTF_EXPORT_PRIVATE bool WTFIsDebuggerAttached();
+
</ins><span class="cx"> #ifdef __cplusplus
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/ChangeLog        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2014-09-18  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Should be able to attach a debugger to a JSContext before anything is executed
+        https://bugs.webkit.org/show_bug.cgi?id=136893
+
+        Reviewed by Timothy Hatcher.
+
+        Automatic inspection is currently disabled for web pages.
+        This just updates the interfaces that changed.
+
+        * WebCore.exp.in:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::connectFrontend):
+        (WebCore::InspectorController::show):
+        * inspector/InspectorController.h:
+        * page/PageDebuggable.cpp:
+        (WebCore::PageDebuggable::connect):
+        * page/PageDebuggable.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::openDummyInspectorFrontend):
+
</ins><span class="cx"> 2014-09-18  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Use fastHasAttribute() / fastGetAttribute() when possible
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -3123,7 +3123,7 @@
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> __ZN7WebCore14SchemeRegistry27shouldTreatURLSchemeAsLocalERKN3WTF6StringE
</span><span class="cx"> __ZN7WebCore15InspectorClient31doDispatchMessageOnFrontendPageEPNS_4PageERKN3WTF6StringE
</span><del>-__ZN7WebCore19InspectorController15connectFrontendEPN9Inspector24InspectorFrontendChannelE
</del><ins>+__ZN7WebCore19InspectorController15connectFrontendEPN9Inspector24InspectorFrontendChannelEb
</ins><span class="cx"> __ZN7WebCore19InspectorController18disconnectFrontendEN9Inspector25InspectorDisconnectReasonE
</span><span class="cx"> __ZN7WebCore19InspectorController18setProfilerEnabledEb
</span><span class="cx"> __ZN7WebCore19InspectorController25evaluateForTestInFrontendERKN3WTF6StringE
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -230,7 +230,7 @@
</span><span class="cx">         m_inspectorFrontendClient-&gt;windowObjectCleared();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
</del><ins>+void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel, bool)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(frontendChannel);
</span><span class="cx">     ASSERT(m_inspectorClient);
</span><span class="lines">@@ -285,7 +285,7 @@
</span><span class="cx">     else {
</span><span class="cx">         InspectorFrontendChannel* frontendChannel = m_inspectorClient-&gt;openInspectorFrontend(this);
</span><span class="cx">         if (frontendChannel)
</span><del>-            connectFrontend(frontendChannel);
</del><ins>+            connectFrontend(frontendChannel, false);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/inspector/InspectorController.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     bool hasLocalFrontend() const;
</span><span class="cx">     bool hasRemoteFrontend() const;
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT void connectFrontend(Inspector::InspectorFrontendChannel*);
</del><ins>+    WEBCORE_EXPORT void connectFrontend(Inspector::InspectorFrontendChannel*, bool isAutomaticInspection);
</ins><span class="cx">     WEBCORE_EXPORT void disconnectFrontend(Inspector::InspectorDisconnectReason);
</span><span class="cx">     void setProcessId(long);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageDebuggablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PageDebuggable.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PageDebuggable.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/page/PageDebuggable.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">     return m_page.inspectorController().hasLocalFrontend();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PageDebuggable::connect(Inspector::InspectorFrontendChannel* channel)
</del><ins>+void PageDebuggable::connect(Inspector::InspectorFrontendChannel* channel, bool isAutomaticInspection)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_page.settings().developerExtrasEnabled()) {
</span><span class="cx">         m_forcedDeveloperExtrasEnabled = true;
</span><span class="lines">@@ -78,7 +78,7 @@
</span><span class="cx"> 
</span><span class="cx">     InspectorController&amp; inspectorController = m_page.inspectorController();
</span><span class="cx">     inspectorController.setHasRemoteFrontend(true);
</span><del>-    inspectorController.connectFrontend(reinterpret_cast&lt;WebCore::InspectorFrontendChannel*&gt;(channel));
</del><ins>+    inspectorController.connectFrontend(reinterpret_cast&lt;WebCore::InspectorFrontendChannel*&gt;(channel), isAutomaticInspection);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void PageDebuggable::disconnect()
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageDebuggableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PageDebuggable.h (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PageDebuggable.h        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/page/PageDebuggable.h        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">     virtual String url() const override;
</span><span class="cx">     virtual bool hasLocalDebugger() const override;
</span><span class="cx"> 
</span><del>-    virtual void connect(Inspector::InspectorFrontendChannel*) override;
</del><ins>+    virtual void connect(Inspector::InspectorFrontendChannel*, bool isAutomaticInspection) override;
</ins><span class="cx">     virtual void disconnect() override;
</span><span class="cx">     virtual void dispatchMessageFromRemoteFrontend(const String&amp; message) override;
</span><span class="cx">     virtual void setIndicating(bool) override;
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (173730 => 173731)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2014-09-18 19:36:36 UTC (rev 173730)
+++ trunk/Source/WebCore/testing/Internals.cpp        2014-09-18 19:47:55 UTC (rev 173731)
</span><span class="lines">@@ -1477,7 +1477,8 @@
</span><span class="cx"> 
</span><span class="cx">     m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
</span><span class="cx"> 
</span><del>-    page-&gt;inspectorController().connectFrontend(m_frontendChannel.get());
</del><ins>+    bool isAutomaticInspection = false;
+    page-&gt;inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection);
</ins><span class="cx"> 
</span><span class="cx">     return m_frontendWindow;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>