Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (173881 => 173882)
--- trunk/Source/_javascript_Core/ChangeLog 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1,3 +1,82 @@
+2014-09-23 Joseph Pecoraro <pecor...@apple.com>
+
+ 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 "is there an auto-inspect" 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.
+
2014-09-22 Filip Pizlo <fpi...@apple.com>
FTL allocatePropertyStorage code should involve less copy-paste
Modified: trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.cpp (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -61,6 +61,7 @@
auto consoleAgent = std::make_unique<JSGlobalObjectConsoleAgent>(m_injectedScriptManager.get());
auto debuggerAgent = std::make_unique<JSGlobalObjectDebuggerAgent>(m_injectedScriptManager.get(), m_globalObject, consoleAgent.get());
+ m_debuggerAgent = debuggerAgent.get();
m_consoleAgent = consoleAgent.get();
m_consoleClient = std::make_unique<JSGlobalObjectConsoleClient>(m_consoleAgent);
@@ -84,7 +85,7 @@
m_injectedScriptManager->disconnect();
}
-void JSGlobalObjectInspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
+void JSGlobalObjectInspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel, bool isAutomaticInspection)
{
ASSERT(!m_inspectorFrontendChannel);
ASSERT(!m_inspectorBackendDispatcher);
@@ -93,6 +94,15 @@
m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel);
m_agents.didCreateFrontendAndBackend(frontendChannel, m_inspectorBackendDispatcher.get());
+
+ 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->enable(nullptr);
+ m_debuggerAgent->pause(nullptr);
+ }
}
void JSGlobalObjectInspectorController::disconnectFrontend(InspectorDisconnectReason reason)
Modified: trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.h (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -47,6 +47,7 @@
class InspectorConsoleAgent;
class InspectorBackendDispatcher;
class InspectorConsoleAgent;
+class InspectorDebuggerAgent;
class InspectorFrontendChannel;
class JSGlobalObjectConsoleClient;
class ScriptCallStack;
@@ -58,7 +59,7 @@
JSGlobalObjectInspectorController(JSC::JSGlobalObject&);
~JSGlobalObjectInspectorController();
- void connectFrontend(InspectorFrontendChannel*);
+ void connectFrontend(InspectorFrontendChannel*, bool isAutomaticInspection);
void disconnectFrontend(InspectorDisconnectReason reason);
void dispatchMessageFromFrontend(const String&);
@@ -85,6 +86,7 @@
std::unique_ptr<InjectedScriptManager> m_injectedScriptManager;
std::unique_ptr<JSGlobalObjectConsoleClient> m_consoleClient;
InspectorConsoleAgent* m_consoleAgent;
+ InspectorDebuggerAgent* m_debuggerAgent;
InspectorAgentRegistry m_agents;
InspectorFrontendChannel* m_inspectorFrontendChannel;
RefPtr<InspectorBackendDispatcher> m_inspectorBackendDispatcher;
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.h (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -52,8 +52,11 @@
void registerDebuggable(RemoteInspectorDebuggable*);
void unregisterDebuggable(RemoteInspectorDebuggable*);
void updateDebuggable(RemoteInspectorDebuggable*);
+ void updateDebuggableAutomaticInspectCandidate(RemoteInspectorDebuggable*);
void sendMessageToRemoteFrontend(unsigned identifier, const String& message);
void setupFailed(unsigned identifier);
+ void setupSucceeded(unsigned identifier);
+ bool waitingForAutomaticInspection(unsigned identifier);
bool enabled() const { return m_enabled; }
bool hasActiveDebugSession() const { return m_hasActiveDebugSession; }
@@ -83,6 +86,8 @@
void updateHasActiveDebugSession();
+ void sendAutomaticInspectionCandidateMessage();
+
virtual void xpcConnectionReceivedMessage(RemoteInspectorXPCConnection*, NSString *messageName, NSDictionary *userInfo) override;
virtual void xpcConnectionFailed(RemoteInspectorXPCConnection*) override;
virtual void xpcConnectionUnhandledMessage(RemoteInspectorXPCConnection*, xpc_object_t) override;
@@ -94,6 +99,8 @@
void receivedIndicateMessage(NSDictionary *userInfo);
void receivedProxyApplicationSetupMessage(NSDictionary *userInfo);
void receivedConnectionDiedMessage(NSDictionary *userInfo);
+ void receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo);
+ void receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo);
static bool startEnabled;
@@ -117,6 +124,9 @@
pid_t m_parentProcessIdentifier;
RetainPtr<CFDataRef> m_parentProcessAuditData;
bool m_shouldSendParentProcessInformation;
+ bool m_automaticInspectionEnabled;
+ bool m_automaticInspectionPaused;
+ unsigned m_automaticInspectionCandidateIdentifier;
};
} // namespace Inspector
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.mm (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.mm 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.mm 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -68,6 +68,17 @@
return sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_GLOBAL_NAME, WIRXPCMachPortName) == 0;
}
+static bool globalAutomaticInspectionState()
+{
+ int token = 0;
+ if (notify_register_check(WIRAutomaticInspectionEnabledState, &token) != NOTIFY_STATUS_OK)
+ return false;
+
+ uint64_t automaticInspectionEnabled = 0;
+ notify_get_state(token, &automaticInspectionEnabled);
+ return automaticInspectionEnabled == 1;
+}
+
static void dispatchAsyncOnQueueSafeForAnyDebuggable(void (^block)())
{
#if PLATFORM(IOS)
@@ -112,6 +123,9 @@
, m_pushScheduled(false)
, m_parentProcessIdentifier(0)
, m_shouldSendParentProcessInformation(false)
+ , m_automaticInspectionEnabled(false)
+ , m_automaticInspectionPaused(false)
+ , m_automaticInspectionCandidateIdentifier(0)
{
}
@@ -170,6 +184,74 @@
pushListingSoon();
}
+void RemoteInspector::updateDebuggableAutomaticInspectCandidate(RemoteInspectorDebuggable* debuggable)
+{
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ unsigned identifier = debuggable->identifier();
+ if (!identifier)
+ return;
+
+ auto result = m_debuggableMap.set(identifier, std::make_pair(debuggable, debuggable->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("Skipping Automatic Inspection Candidate with pageId(%u) because we are already paused waiting for pageId(%u)", 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<std::mutex> lock(m_mutex);
+ if (m_automaticInspectionCandidateIdentifier == identifier) {
+ LOG_ERROR("Skipping Automatic Inspection Candidate with pageId(%u) because we failed to receive a response in time.", m_automaticInspectionCandidateIdentifier);
+ m_automaticInspectionPaused = false;
+ }
+ });
+ }
+
+ debuggable->pauseWaitingForAutomaticInspection();
+
+ {
+ std::lock_guard<std::mutex> 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->sendMessage(WIRAutomaticInspectionCandidateMessage, details);
+}
+
void RemoteInspector::sendMessageToRemoteFrontend(unsigned identifier, const String& message)
{
std::lock_guard<std::mutex> lock(m_mutex);
@@ -198,9 +280,26 @@
updateHasActiveDebugSession();
+ if (identifier == m_automaticInspectionCandidateIdentifier)
+ m_automaticInspectionPaused = false;
+
pushListingSoon();
}
+void RemoteInspector::setupSucceeded(unsigned identifier)
+{
+ std::lock_guard<std::mutex> 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;
+}
+
void RemoteInspector::start()
{
std::lock_guard<std::mutex> lock(m_mutex);
@@ -210,6 +309,12 @@
m_enabled = true;
+ // 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(&once, ^{
+ m_automaticInspectionEnabled = globalAutomaticInspectionState();
+ });
+
notify_register_dispatch(WIRServiceAvailableNotification, &m_notifyToken, m_xpcQueue, ^(int) {
RemoteInspector::shared().setupXPCConnectionIfNeeded();
});
@@ -239,6 +344,8 @@
updateHasActiveDebugSession();
+ m_automaticInspectionPaused = false;
+
if (m_xpcConnection) {
switch (source) {
case StopSource::API:
@@ -270,7 +377,12 @@
m_xpcConnection->sendMessage(@"syn", nil); // Send a simple message to initialize the XPC connection.
xpc_release(connection);
- pushListingSoon();
+ if (m_automaticInspectionCandidateIdentifier) {
+ // We already have a debuggable waiting to be automatically inspected.
+ pushListingNow();
+ sendAutomaticInspectionCandidateMessage();
+ } else
+ pushListingSoon();
}
#pragma mark - Proxy Application Information
@@ -314,6 +426,10 @@
receivedProxyApplicationSetupMessage(userInfo);
else if ([messageName isEqualToString:WIRConnectionDiedMessage])
receivedConnectionDiedMessage(userInfo);
+ else if ([messageName isEqualToString:WIRAutomaticInspectionConfigurationMessage])
+ receivedAutomaticInspectionConfigurationMessage(userInfo);
+ else if ([messageName isEqualToString:WIRAutomaticInspectionRejectMessage])
+ receivedAutomaticInspectionRejectMessage(userInfo);
else
NSLog(@"Unrecognized RemoteInspector XPC Message: %@", messageName);
}
@@ -334,6 +450,8 @@
updateHasActiveDebugSession();
+ m_automaticInspectionPaused = false;
+
// The connection will close itself.
m_xpcConnection = nullptr;
}
@@ -433,6 +551,7 @@
// Legacy iOS WebKit 1 had a notification. This will need to be smarter with WebKit2.
}
+
#pragma mark - Received XPC Messages
void RemoteInspector::receivedSetupMessage(NSDictionary *userInfo)
@@ -461,7 +580,8 @@
RemoteInspectorDebuggable* debuggable = it->value.first;
RemoteInspectorDebuggableInfo debuggableInfo = it->value.second;
RefPtr<RemoteInspectorDebuggableConnection> connection = adoptRef(new RemoteInspectorDebuggableConnection(debuggable, connectionIdentifier, sender, debuggableInfo.type));
- if (!connection->setup()) {
+ bool isAutomaticInspection = m_automaticInspectionCandidateIdentifier == debuggable->identifier();
+ if (!connection->setup(isAutomaticInspection)) {
connection->close();
return;
}
@@ -593,6 +713,23 @@
updateHasActiveDebugSession();
}
+void RemoteInspector::receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo)
+{
+ m_automaticInspectionEnabled = [[userInfo objectForKey:WIRAutomaticInspectionEnabledKey] boolValue];
+
+ if (!m_automaticInspectionEnabled && 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;
+}
+
} // namespace Inspector
#endif // ENABLE(REMOTE_INSPECTOR)
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorConstants.h (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorConstants.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorConstants.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -37,12 +37,14 @@
#define WIRServiceAvailabilityCheckNotification "com.apple.webinspectord.availability_check"
#define WIRServiceEnabledNotification "com.apple.webinspectord.enabled"
#define WIRServiceDisabledNotification "com.apple.webinspectord.disabled"
+#define WIRAutomaticInspectionEnabledState "com.apple.webinspectord.automatic_inspection_enabled"
#define WIRApplicationIdentifierKey @"WIRApplicationIdentifierKey"
#define WIRApplicationBundleIdentifierKey @"WIRApplicationBundleIdentifierKey"
#define WIRApplicationNameKey @"WIRApplicationNameKey"
#define WIRIsApplicationProxyKey @"WIRIsApplicationProxyKey"
+#define WIRIsApplicationActiveKey @"WIRIsApplicationActiveKey"
#define WIRHostApplicationIdentifierKey @"WIRHostApplicationIdentifierKey"
#define WIRHostApplicationNameKey @"WIRHostApplicationNameKey"
#define WIRConnectionIdentifierKey @"WIRConnectionIdentifierKey"
@@ -71,6 +73,12 @@
#define WIRTypeJavaScript @"WIRTypeJavaScript"
#define WIRTypeWeb @"WIRTypeWeb"
+#define WIRAutomaticInspectionEnabledKey @"WIRAutomaticInspectionEnabledKey"
+#define WIRAutomaticInspectionSessionIdentifierKey @"WIRAutomaticInspectionSessionIdentifierKey"
+#define WIRAutomaticInspectionConfigurationMessage @"WIRAutomaticInspectionConfigurationMessage"
+#define WIRAutomaticInspectionRejectMessage @"WIRAutomaticInspectionRejectMessage"
+#define WIRAutomaticInspectionCandidateMessage @"WIRAutomaticInspectionCandidateMessage"
+
// These definitions are shared with a Simulator webinspectord and
// OS X process communicating with it.
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.cpp (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -28,6 +28,7 @@
#if ENABLE(REMOTE_INSPECTOR)
+#include "EventLoop.h"
#include "InspectorFrontendChannel.h"
#include "RemoteInspector.h"
@@ -61,7 +62,10 @@
m_allowed = allowed;
- update();
+ if (m_allowed && automaticInspectionAllowed())
+ RemoteInspector::shared().updateDebuggableAutomaticInspectCandidate(this);
+ else
+ RemoteInspector::shared().updateDebuggable(this);
}
RemoteInspectorDebuggableInfo RemoteInspectorDebuggable::info() const
@@ -76,6 +80,17 @@
return info;
}
+void RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection()
+{
+ ASSERT(m_identifier);
+ ASSERT(m_allowed);
+ ASSERT(automaticInspectionAllowed());
+
+ EventLoop loop;
+ while (RemoteInspector::shared().waitingForAutomaticInspection(identifier()) && !loop.ended())
+ loop.cycle();
+}
+
} // namespace Inspector
#endif // ENABLE(REMOTE_INSPECTOR)
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.h (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -62,11 +62,14 @@
virtual String url() const { return String(); } // Web
virtual bool hasLocalDebugger() const = 0;
- virtual void connect(InspectorFrontendChannel*) = 0;
+ virtual void connect(InspectorFrontendChannel*, bool isAutomaticInspection) = 0;
virtual void disconnect() = 0;
virtual void dispatchMessageFromRemoteFrontend(const String& message) = 0;
virtual void setIndicating(bool) { } // Default is to do nothing.
+ virtual bool automaticInspectionAllowed() const { return false; }
+ virtual void pauseWaitingForAutomaticInspection();
+
private:
unsigned m_identifier;
bool m_allowed;
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.h (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -84,7 +84,7 @@
NSString *connectionIdentifier() const;
unsigned identifier() const { return m_identifier; }
- bool setup();
+ bool setup(bool isAutomaticInspection);
void close();
void closeFromDebuggable();
Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.mm (173881 => 173882)
--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.mm 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.mm 2014-09-23 18:38:24 UTC (rev 173882)
@@ -149,7 +149,7 @@
RemoteInspectorQueueTaskOnGlobalQueue(block);
}
-bool RemoteInspectorDebuggableConnection::setup()
+bool RemoteInspectorDebuggableConnection::setup(bool isAutomaticInspection)
{
std::lock_guard<std::mutex> lock(m_debuggableMutex);
@@ -164,8 +164,9 @@
RemoteInspector::shared().setupFailed(identifier());
m_debuggable = nullptr;
} else {
- m_debuggable->connect(this);
+ m_debuggable->connect(this, isAutomaticInspection);
m_connected = true;
+ RemoteInspector::shared().setupSucceeded(identifier());
}
}
deref();
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.cpp (173881 => 173882)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -31,6 +31,7 @@
#include "InspectorAgentBase.h"
#include "InspectorFrontendChannel.h"
#include "JSGlobalObject.h"
+#include "JSLock.h"
#include "RemoteInspector.h"
using namespace Inspector;
@@ -48,11 +49,11 @@
return name.isEmpty() ? ASCIILiteral("JSContext") : name;
}
-void JSGlobalObjectDebuggable::connect(InspectorFrontendChannel* frontendChannel)
+void JSGlobalObjectDebuggable::connect(InspectorFrontendChannel* frontendChannel, bool automaticInspection)
{
JSLockHolder locker(&m_globalObject.vm());
- m_globalObject.inspectorController().connectFrontend(frontendChannel);
+ m_globalObject.inspectorController().connectFrontend(frontendChannel, automaticInspection);
}
void JSGlobalObjectDebuggable::disconnect()
@@ -69,6 +70,12 @@
m_globalObject.inspectorController().dispatchMessageFromFrontend(message);
}
+void JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection()
+{
+ JSC::JSLock::DropAllLocks dropAllLocks(&m_globalObject.vm());
+ RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection();
+}
+
} // namespace JSC
#endif // ENABLE(REMOTE_INSPECTOR)
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.h (173881 => 173882)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -51,10 +51,13 @@
virtual String name() const override;
virtual bool hasLocalDebugger() const override { return false; }
- virtual void connect(Inspector::InspectorFrontendChannel*) override;
+ virtual void connect(Inspector::InspectorFrontendChannel*, bool automaticInspection) override;
virtual void disconnect() override;
virtual void dispatchMessageFromRemoteFrontend(const String& message) override;
+ virtual bool automaticInspectionAllowed() const override { return true; }
+ virtual void pauseWaitingForAutomaticInspection() override;
+
private:
JSGlobalObject& m_globalObject;
};
Modified: trunk/Source/WTF/ChangeLog (173881 => 173882)
--- trunk/Source/WTF/ChangeLog 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WTF/ChangeLog 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1,3 +1,18 @@
+2014-09-23 Joseph Pecoraro <pecor...@apple.com>
+
+ 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:
+
2014-09-22 Sam Weinig <s...@webkit.org>
Eliminate redundant PtrHash specializations
Modified: trunk/Source/WTF/wtf/Assertions.cpp (173881 => 173882)
--- trunk/Source/WTF/wtf/Assertions.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WTF/wtf/Assertions.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -63,6 +63,11 @@
#include <windows.h>
#endif
+#if OS(DARWIN)
+#include <sys/sysctl.h>
+#include <unistd.h>
+#endif
+
#if OS(DARWIN) || (OS(LINUX) && !defined(__UCLIBC__))
#include <cxxabi.h>
#include <dlfcn.h>
@@ -385,6 +390,20 @@
#endif
}
+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]), &info, &size, nullptr, 0) == -1)
+ return false;
+ return info.kp_proc.p_flag & P_TRACED;
+#else
+ return false;
+#endif
+}
+
void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
{
va_list args;
Modified: trunk/Source/WTF/wtf/Assertions.h (173881 => 173882)
--- trunk/Source/WTF/wtf/Assertions.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WTF/wtf/Assertions.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -38,6 +38,7 @@
#include <inttypes.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stddef.h>
#ifdef NDEBUG
@@ -145,6 +146,8 @@
WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
+WTF_EXPORT_PRIVATE bool WTFIsDebuggerAttached();
+
#ifdef __cplusplus
}
#endif
Modified: trunk/Source/WebCore/ChangeLog (173881 => 173882)
--- trunk/Source/WebCore/ChangeLog 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/ChangeLog 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1,3 +1,24 @@
+2014-09-23 Joseph Pecoraro <pecor...@apple.com>
+
+ 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):
+
2014-09-23 Eduardo Lima Mitev <el...@igalia.com>
[GTK] Adds implementation of subtle crypto HMAC algorithm
Modified: trunk/Source/WebCore/WebCore.exp.in (173881 => 173882)
--- trunk/Source/WebCore/WebCore.exp.in 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/WebCore.exp.in 2014-09-23 18:38:24 UTC (rev 173882)
@@ -3122,7 +3122,7 @@
#if ENABLE(INSPECTOR)
__ZN7WebCore14SchemeRegistry27shouldTreatURLSchemeAsLocalERKN3WTF6StringE
__ZN7WebCore15InspectorClient31doDispatchMessageOnFrontendPageEPNS_4PageERKN3WTF6StringE
-__ZN7WebCore19InspectorController15connectFrontendEPN9Inspector24InspectorFrontendChannelE
+__ZN7WebCore19InspectorController15connectFrontendEPN9Inspector24InspectorFrontendChannelEb
__ZN7WebCore19InspectorController18disconnectFrontendEN9Inspector25InspectorDisconnectReasonE
__ZN7WebCore19InspectorController18setProfilerEnabledEb
__ZN7WebCore19InspectorController25evaluateForTestInFrontendERKN3WTF6StringE
Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (173881 => 173882)
--- trunk/Source/WebCore/inspector/InspectorController.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -230,7 +230,7 @@
m_inspectorFrontendClient->windowObjectCleared();
}
-void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
+void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel, bool)
{
ASSERT(frontendChannel);
ASSERT(m_inspectorClient);
@@ -285,7 +285,7 @@
else {
InspectorFrontendChannel* frontendChannel = m_inspectorClient->openInspectorFrontend(this);
if (frontendChannel)
- connectFrontend(frontendChannel);
+ connectFrontend(frontendChannel, false);
}
}
Modified: trunk/Source/WebCore/inspector/InspectorController.h (173881 => 173882)
--- trunk/Source/WebCore/inspector/InspectorController.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/inspector/InspectorController.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -93,7 +93,7 @@
bool hasLocalFrontend() const;
bool hasRemoteFrontend() const;
- WEBCORE_EXPORT void connectFrontend(Inspector::InspectorFrontendChannel*);
+ WEBCORE_EXPORT void connectFrontend(Inspector::InspectorFrontendChannel*, bool isAutomaticInspection);
WEBCORE_EXPORT void disconnectFrontend(Inspector::InspectorDisconnectReason);
void setProcessId(long);
Modified: trunk/Source/WebCore/page/PageDebuggable.cpp (173881 => 173882)
--- trunk/Source/WebCore/page/PageDebuggable.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/page/PageDebuggable.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -68,7 +68,7 @@
return m_page.inspectorController().hasLocalFrontend();
}
-void PageDebuggable::connect(Inspector::InspectorFrontendChannel* channel)
+void PageDebuggable::connect(Inspector::InspectorFrontendChannel* channel, bool isAutomaticInspection)
{
if (!m_page.settings().developerExtrasEnabled()) {
m_forcedDeveloperExtrasEnabled = true;
@@ -78,7 +78,7 @@
InspectorController& inspectorController = m_page.inspectorController();
inspectorController.setHasRemoteFrontend(true);
- inspectorController.connectFrontend(reinterpret_cast<WebCore::InspectorFrontendChannel*>(channel));
+ inspectorController.connectFrontend(reinterpret_cast<WebCore::InspectorFrontendChannel*>(channel), isAutomaticInspection);
}
void PageDebuggable::disconnect()
Modified: trunk/Source/WebCore/page/PageDebuggable.h (173881 => 173882)
--- trunk/Source/WebCore/page/PageDebuggable.h 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/page/PageDebuggable.h 2014-09-23 18:38:24 UTC (rev 173882)
@@ -47,7 +47,7 @@
virtual String url() const override;
virtual bool hasLocalDebugger() const override;
- virtual void connect(Inspector::InspectorFrontendChannel*) override;
+ virtual void connect(Inspector::InspectorFrontendChannel*, bool isAutomaticInspection) override;
virtual void disconnect() override;
virtual void dispatchMessageFromRemoteFrontend(const String& message) override;
virtual void setIndicating(bool) override;
Modified: trunk/Source/WebCore/testing/Internals.cpp (173881 => 173882)
--- trunk/Source/WebCore/testing/Internals.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebCore/testing/Internals.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1477,7 +1477,8 @@
m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
- page->inspectorController().connectFrontend(m_frontendChannel.get());
+ bool isAutomaticInspection = false;
+ page->inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection);
return m_frontendWindow;
}
Modified: trunk/Source/WebKit/ChangeLog (173881 => 173882)
--- trunk/Source/WebKit/ChangeLog 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebKit/ChangeLog 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1,3 +1,12 @@
+2014-09-23 Joseph Pecoraro <pecor...@apple.com>
+
+ 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.
+
+ * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
+
2014-09-23 Brent Fulgham <bfulg...@apple.com>
[Win] Correct 64-bit Windows export definitions after r173804.
Modified: trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in (173881 => 173882)
--- trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in 2014-09-23 18:38:24 UTC (rev 173882)
@@ -219,7 +219,7 @@
symbolWithPointer(??1InspectorFrontendClientLocal@WebCore@@UAE@XZ, ??1InspectorFrontendClientLocal@WebCore@@UEAA@XZ)
symbolWithPointer(?changeAttachedWindowHeight@InspectorFrontendClientLocal@WebCore@@UAEXI@Z, ?changeAttachedWindowHeight@InspectorFrontendClientLocal@WebCore@@UEAAXI@Z)
symbolWithPointer(?changeAttachedWindowWidth@InspectorFrontendClientLocal@WebCore@@UAEXI@Z, ?changeAttachedWindowWidth@InspectorFrontendClientLocal@WebCore@@UEAAXI@Z)
- symbolWithPointer(?connectFrontend@InspectorController@WebCore@@QAEXPAVInspectorFrontendChannel@Inspector@@@Z, ?connectFrontend@InspectorController@WebCore@@QEAAXPEAVInspectorFrontendChannel@Inspector@@@Z)
+ symbolWithPointer(?connectFrontend@InspectorController@WebCore@@QAEXPAVInspectorFrontendChannel@Inspector@@_N@Z, ?connectFrontend@InspectorController@WebCore@@QAEXPAVInspectorFrontendChannel@Inspector@@_N@Z)
symbolWithPointer(?doDispatchMessageOnFrontendPage@InspectorClient@WebCore@@SA_NPAVPage@2@ABVString@WTF@@@Z, ?doDispatchMessageOnFrontendPage@InspectorClient@WebCore@@SA_NPEAVPage@2@AEBVString@WTF@@@Z)
symbolWithPointer(?frontendLoaded@InspectorFrontendClientLocal@WebCore@@UAEXXZ, ?frontendLoaded@InspectorFrontendClientLocal@WebCore@@UEAAXXZ)
symbolWithPointer(?getProperty@Settings@InspectorFrontendClientLocal@WebCore@@UAE?AVString@WTF@@ABV45@@Z, ?getProperty@Settings@InspectorFrontendClientLocal@WebCore@@UEAA?AVString@WTF@@AEBV45@@Z)
Modified: trunk/Source/WebKit2/ChangeLog (173881 => 173882)
--- trunk/Source/WebKit2/ChangeLog 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebKit2/ChangeLog 2014-09-23 18:38:24 UTC (rev 173882)
@@ -1,3 +1,13 @@
+2014-09-23 Joseph Pecoraro <pecor...@apple.com>
+
+ 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.
+
+ * WebProcess/WebPage/WebInspector.cpp:
+ (WebKit::WebInspector::remoteFrontendConnected):
+
2014-09-22 Daniel Bates <daba...@apple.com>
[Cocoa] Add UI delegate callback when window.close() is called
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp (173881 => 173882)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp 2014-09-23 18:24:02 UTC (rev 173881)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp 2014-09-23 18:38:24 UTC (rev 173882)
@@ -331,8 +331,9 @@
ASSERT(!m_remoteFrontendConnected);
// Switching between in-process and remote inspectors isn't supported yet.
ASSERT(!m_inspectorPage);
-
- m_page->corePage()->inspectorController().connectFrontend(m_frontendChannel);
+
+ bool isAutomaticInspection = false;
+ m_page->corePage()->inspectorController().connectFrontend(m_frontendChannel, isAutomaticInspection);
m_remoteFrontendConnected = true;
}