Add a WebKitMessageRecorder DTrace provider, exposing IPC details to DTrace
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Jan 2015 02:32:24 +0000 (02:32 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Jan 2015 02:32:24 +0000 (02:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140673

Reviewed by Sam Weinig.

* Platform/IPC/ArgumentCoders.cpp:
(IPC::ArgumentCoder<uuid_t>::encode):
(IPC::ArgumentCoder<uuid_t>::decode):
* Platform/IPC/ArgumentCoders.h:
Add a uuid_t (simple) argument coder.
Fix a mis-named header-guard #ifdef.

* Platform/IPC/Connection.cpp:
(IPC::Connection::dispatchWorkQueueMessageReceiverMessage):
(IPC::Connection::dispatchSyncMessage):
Sync message replies inherit the message UUID from the incoming sync message.

(IPC::Connection::sendMessage):
(IPC::Connection::waitForMessage):
(IPC::Connection::sendSyncMessage):
(IPC::Connection::sendSyncMessageFromSecondaryThread):
Record outgoing messages. Because sendSyncMessage calls sendMessage,
we have to explicitly avoid recording the message twice.

(IPC::Connection::dispatchMessage):
Record the incoming message.

(IPC::Connection::remoteProcessID):
Add remoteProcessID(), which tries to determine the pid of the remote process.

* Platform/IPC/Connection.h:
(IPC::Connection::xpcConnection):
This can be const.

(IPC::Connection::isValid):
Make this public.

* Platform/IPC/MessageDecoder.cpp:
(IPC::MessageDecoder::MessageDecoder):
* Platform/IPC/MessageDecoder.h:
(IPC::MessageDecoder::setMessageProcessingToken):
(IPC::MessageDecoder::UUID):
Decode and store the message UUID.
Store a MessageProcessingToken for the lifetime of the MessageDecoder;
this ensures that all time spent processing the incoming message will be
counted against that message.

* Platform/IPC/MessageEncoder.cpp:
(IPC::MessageEncoder::MessageEncoder):
By default, create a new UUID for the message. Alternatively, allow clients
to pass the message UUID in (used for sync message replies).
Store the messageReceiverName and messageName.

(IPC::MessageEncoder::encodeHeader):
Factor encodeHeader() out of the constructors so most of their code can be shared.

(IPC::MessageEncoder::isSyncMessage):
(IPC::MessageEncoder::shouldDispatchMessageWhenWaitingForSyncReply):
Add getters for these flags.

* Platform/IPC/MessageEncoder.h:
(IPC::MessageEncoder::messageReceiverName):
(IPC::MessageEncoder::messageName):
(IPC::MessageEncoder::destinationID):
(IPC::MessageEncoder::UUID):

* Platform/IPC/MessageRecorder.h: Added.
* Platform/IPC/MessageRecorder.cpp: Added.
(MessageRecorder::MessageRecorder):
Add a class that interfaces with a custom DTrace provider to log incoming and outgoing messages.

(MessageRecorder::shared):
(MessageRecorder::isEnabled):
Determine if either of the message probes are enabled. If not, we'll avoid most of the
work associated with MessageRecorder.

(MessageRecorder::recordOutgoingMessage):
(MessageRecorder::recordIncomingMessage):
Build a WebKitMessageRecord and MessageProcessingToken from the Message(De|En)coder.
Once the MessageProcessingToken is deallocated, the probe will be invoked with the WebKitMessageRecord.

(MessageRecorder::MessageProcessingToken::MessageProcessingToken):
(MessageRecorder::MessageProcessingToken::~MessageProcessingToken):
Keep track of when the token is created and destroyed; these are considered the beginning
and ending "processing" times of the message (and as such the token should be kept alive for
exactly as long as the message is being processed).

* Platform/IPC/MessageRecorderProbes.d: Added.
Add a DTrace provider source file with two probes, message_sent and message_received.
The struct must match the struct in MessageRecorder.h.

* Platform/IPC/ProcessType.h: Added.
Add an enum of process types.

* WebKit2.xcodeproj/project.pbxproj:

* DatabaseProcess/DatabaseProcess.h:
* DatabaseProcess/DatabaseToWebProcessConnection.h:
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/NetworkProcess.h:
* WebProcess/Databases/WebToDatabaseProcessConnection.h:
* WebProcess/Network/NetworkProcessConnection.h:
* WebProcess/Plugins/PluginProcessConnection.h:
* WebProcess/WebPage/WebInspector.h:
* WebProcess/WebPage/WebInspectorUI.h:
* WebProcess/WebProcess.h:
* UIProcess/Databases/DatabaseProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Plugins/PluginProcessProxy.h:
* UIProcess/WebProcessProxy.h:
* PluginProcess/PluginProcess.h:
* PluginProcess/WebProcessConnection.h:
Annotate Connection::Clients with process types.

* Scripts/dtrace/trace-webkit2-messages.d: Added.
Add a DTrace script that outputs a small blob of JSON per message.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@179326 268f45cc-cd09-0410-ab3c-d52691b4dbfc

33 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/DatabaseProcess.h
Source/WebKit2/DatabaseProcess/DatabaseToWebProcessConnection.h
Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h
Source/WebKit2/NetworkProcess/NetworkProcess.h
Source/WebKit2/Platform/IPC/ArgumentCoders.cpp
Source/WebKit2/Platform/IPC/ArgumentCoders.h
Source/WebKit2/Platform/IPC/Connection.cpp
Source/WebKit2/Platform/IPC/Connection.h
Source/WebKit2/Platform/IPC/MessageDecoder.cpp
Source/WebKit2/Platform/IPC/MessageDecoder.h
Source/WebKit2/Platform/IPC/MessageEncoder.cpp
Source/WebKit2/Platform/IPC/MessageEncoder.h
Source/WebKit2/Platform/IPC/MessageRecorder.cpp [new file with mode: 0644]
Source/WebKit2/Platform/IPC/MessageRecorder.h [new file with mode: 0644]
Source/WebKit2/Platform/IPC/MessageRecorderProbes.d [new file with mode: 0644]
Source/WebKit2/Platform/IPC/ProcessType.h [new file with mode: 0644]
Source/WebKit2/Platform/IPC/mac/ConnectionMac.mm
Source/WebKit2/PluginProcess/PluginProcess.h
Source/WebKit2/PluginProcess/WebProcessConnection.h
Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.h
Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h
Source/WebKit2/UIProcess/WebProcessProxy.h
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
Source/WebKit2/WebProcess/Databases/WebToDatabaseProcessConnection.h
Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h
Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h
Source/WebKit2/WebProcess/WebPage/WebInspector.h
Source/WebKit2/WebProcess/WebPage/WebInspectorUI.h
Source/WebKit2/WebProcess/WebProcess.h
Tools/ChangeLog
Tools/Scripts/dtrace/trace-webkit2-messages.d [new file with mode: 0755]

index c04c9a33c34ee135521dbe80cf1ea77c921b4169..f00f0d776c58fdbe892e4e767a19849442ce7126 100644 (file)
@@ -1,3 +1,119 @@
+2015-01-28  Timothy Horton  <timothy_horton@apple.com>
+
+        Add a WebKitMessageRecorder DTrace provider, exposing IPC details to DTrace
+        https://bugs.webkit.org/show_bug.cgi?id=140673
+
+        Reviewed by Sam Weinig.
+
+        * Platform/IPC/ArgumentCoders.cpp:
+        (IPC::ArgumentCoder<uuid_t>::encode):
+        (IPC::ArgumentCoder<uuid_t>::decode):
+        * Platform/IPC/ArgumentCoders.h:
+        Add a uuid_t (simple) argument coder.
+        Fix a mis-named header-guard #ifdef.
+
+        * Platform/IPC/Connection.cpp:
+        (IPC::Connection::dispatchWorkQueueMessageReceiverMessage):
+        (IPC::Connection::dispatchSyncMessage):
+        Sync message replies inherit the message UUID from the incoming sync message.
+
+        (IPC::Connection::sendMessage):
+        (IPC::Connection::waitForMessage):
+        (IPC::Connection::sendSyncMessage):
+        (IPC::Connection::sendSyncMessageFromSecondaryThread):
+        Record outgoing messages. Because sendSyncMessage calls sendMessage,
+        we have to explicitly avoid recording the message twice.
+
+        (IPC::Connection::dispatchMessage):
+        Record the incoming message.
+
+        (IPC::Connection::remoteProcessID):
+        Add remoteProcessID(), which tries to determine the pid of the remote process.
+
+        * Platform/IPC/Connection.h:
+        (IPC::Connection::xpcConnection):
+        This can be const.
+
+        (IPC::Connection::isValid):
+        Make this public.
+
+        * Platform/IPC/MessageDecoder.cpp:
+        (IPC::MessageDecoder::MessageDecoder):
+        * Platform/IPC/MessageDecoder.h:
+        (IPC::MessageDecoder::setMessageProcessingToken):
+        (IPC::MessageDecoder::UUID):
+        Decode and store the message UUID.
+        Store a MessageProcessingToken for the lifetime of the MessageDecoder;
+        this ensures that all time spent processing the incoming message will be
+        counted against that message.
+
+        * Platform/IPC/MessageEncoder.cpp:
+        (IPC::MessageEncoder::MessageEncoder):
+        By default, create a new UUID for the message. Alternatively, allow clients
+        to pass the message UUID in (used for sync message replies).
+        Store the messageReceiverName and messageName.
+
+        (IPC::MessageEncoder::encodeHeader):
+        Factor encodeHeader() out of the constructors so most of their code can be shared.
+
+        (IPC::MessageEncoder::isSyncMessage):
+        (IPC::MessageEncoder::shouldDispatchMessageWhenWaitingForSyncReply):
+        Add getters for these flags.
+
+        * Platform/IPC/MessageEncoder.h:
+        (IPC::MessageEncoder::messageReceiverName):
+        (IPC::MessageEncoder::messageName):
+        (IPC::MessageEncoder::destinationID):
+        (IPC::MessageEncoder::UUID):
+
+        * Platform/IPC/MessageRecorder.h: Added.
+        * Platform/IPC/MessageRecorder.cpp: Added.
+        (MessageRecorder::MessageRecorder):
+        Add a class that interfaces with a custom DTrace provider to log incoming and outgoing messages.
+
+        (MessageRecorder::shared):
+        (MessageRecorder::isEnabled):
+        Determine if either of the message probes are enabled. If not, we'll avoid most of the
+        work associated with MessageRecorder.
+
+        (MessageRecorder::recordOutgoingMessage):
+        (MessageRecorder::recordIncomingMessage):
+        Build a WebKitMessageRecord and MessageProcessingToken from the Message(De|En)coder.
+        Once the MessageProcessingToken is deallocated, the probe will be invoked with the WebKitMessageRecord.
+
+        (MessageRecorder::MessageProcessingToken::MessageProcessingToken):
+        (MessageRecorder::MessageProcessingToken::~MessageProcessingToken):
+        Keep track of when the token is created and destroyed; these are considered the beginning
+        and ending "processing" times of the message (and as such the token should be kept alive for
+        exactly as long as the message is being processed).
+
+        * Platform/IPC/MessageRecorderProbes.d: Added.
+        Add a DTrace provider source file with two probes, message_sent and message_received.
+        The struct must match the struct in MessageRecorder.h.
+        
+        * Platform/IPC/ProcessType.h: Added.
+        Add an enum of process types.
+
+        * WebKit2.xcodeproj/project.pbxproj:
+
+        * DatabaseProcess/DatabaseProcess.h:
+        * DatabaseProcess/DatabaseToWebProcessConnection.h:
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        * NetworkProcess/NetworkProcess.h:
+        * WebProcess/Databases/WebToDatabaseProcessConnection.h:
+        * WebProcess/Network/NetworkProcessConnection.h:
+        * WebProcess/Plugins/PluginProcessConnection.h:
+        * WebProcess/WebPage/WebInspector.h:
+        * WebProcess/WebPage/WebInspectorUI.h:
+        * WebProcess/WebProcess.h:
+        * UIProcess/Databases/DatabaseProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Plugins/PluginProcessProxy.h:
+        * UIProcess/WebProcessProxy.h:
+        * PluginProcess/PluginProcess.h:
+        * PluginProcess/WebProcessConnection.h:
+        Annotate Connection::Clients with process types.
+        
 2015-01-28  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Crash closing inspected page with frequent activity
index b3aff2859154f9f9dcb1b2fa1b404dad9172749e..b2b24eea13ffb81f3cf79047dfc7018443f5aa16 100644 (file)
@@ -82,6 +82,8 @@ private:
     virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Database; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::UI; }
     void didReceiveDatabaseProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
 
     // Message Handlers
index 06f85bf8d0735cc5be38af7818f11014e691aab5..59c40d37329b8bc8372033e3805c926efa1643b8 100644 (file)
@@ -51,6 +51,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Database; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Web; }
     void didReceiveDatabaseToWebProcessConnectionMessage(IPC::Connection&, IPC::MessageDecoder&);
 
     // IPC::MessageSender
index 06cc88e14b2771e26a545f907afd859cd3973fe1..946d2eadeee38f1cb3fb3f1940c6a97b69c4f8e1 100644 (file)
@@ -65,6 +65,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
     virtual void didClose(IPC::Connection&);
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName);
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Network; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Web; }
 
     // Message handlers.
     void didReceiveNetworkConnectionToWebProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
index b9dcc6bf87dc7b585eff649c8a09866c7cd2af0b..d57f751aeb6184c9f1fa110b28f37f21650311f6 100644 (file)
@@ -99,6 +99,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Network; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::UI; }
 
     // DownloadManager::Client
     virtual void didCreateDownload() override;
index 39f3e0797e1678560ea10afd54ed68d550f7ff63..f72eac2676273248267bbbed78eb36617b50122d 100644 (file)
@@ -162,4 +162,14 @@ bool ArgumentCoder<String>::decode(ArgumentDecoder& decoder, String& result)
     return decodeStringText<UChar>(decoder, length, result);
 }
 
+void ArgumentCoder<uuid_t>::encode(ArgumentEncoder& encoder, const uuid_t& uuid)
+{
+    SimpleArgumentCoder<uuid_t>::encode(encoder, uuid);
+}
+
+bool ArgumentCoder<uuid_t>::decode(ArgumentDecoder& decoder, uuid_t& uuid)
+{
+    return SimpleArgumentCoder<uuid_t>::decode(decoder, uuid);
+}
+
 } // namespace IPC
index 462ce376debd6cd2170a18b18342b0ccf5a5b688..62da34403453da8908a7854047c680e71b3aab2a 100644 (file)
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef SimpleArgumentCoder_h
-#define SimpleArgumentCoder_h
+#ifndef ArgumentCoders_h
+#define ArgumentCoders_h
 
 #include "ArgumentDecoder.h"
 #include "ArgumentEncoder.h"
 #include <utility>
+#include <uuid/uuid.h>
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
@@ -298,6 +299,11 @@ template<> struct ArgumentCoder<String> {
     static bool decode(ArgumentDecoder&, String&);
 };
 
+template<> struct ArgumentCoder<uuid_t> {
+    static void encode(ArgumentEncoder&, const uuid_t&);
+    static bool decode(ArgumentDecoder&, uuid_t&);
+};
+
 } // namespace IPC
 
 #endif // ArgumentCoders_h
index 7b8ab209669c602f43dc912a45791f535a71840c..aca77bd87caa25af0016abcc4ebf1432983501ec 100644 (file)
@@ -317,7 +317,7 @@ void Connection::dispatchWorkQueueMessageReceiverMessage(WorkQueueMessageReceive
         return;
     }
 
-    auto replyEncoder = std::make_unique<MessageEncoder>("IPC", "SyncMessageReply", syncRequestID);
+    auto replyEncoder = std::make_unique<MessageEncoder>("IPC", "SyncMessageReply", syncRequestID, incomingMessageDecoder->UUID());
 
     // Hand off both the decoder and encoder to the work queue message receiver.
     workQueueMessageReceiver->didReceiveSyncMessage(*this, *decoder, replyEncoder);
@@ -369,7 +369,7 @@ std::unique_ptr<MessageEncoder> Connection::createSyncMessageEncoder(StringRefer
     return encoder;
 }
 
-bool Connection::sendMessage(std::unique_ptr<MessageEncoder> encoder, unsigned messageSendFlags)
+bool Connection::sendMessage(std::unique_ptr<MessageEncoder> encoder, unsigned messageSendFlags, bool alreadyRecordedMessage)
 {
     if (!isValid())
         return false;
@@ -379,6 +379,10 @@ bool Connection::sendMessage(std::unique_ptr<MessageEncoder> encoder, unsigned m
             || m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount))
         encoder->setShouldDispatchMessageWhenWaitingForSyncReply(true);
 
+    std::unique_ptr<MessageRecorder::MessageProcessingToken> token;
+    if (!alreadyRecordedMessage)
+        token = MessageRecorder::recordOutgoingMessage(*this, *encoder);
+
     {
         std::lock_guard<std::mutex> lock(m_outgoingMessagesMutex);
         m_outgoingMessages.append(WTF::move(encoder));
@@ -473,8 +477,10 @@ std::unique_ptr<MessageDecoder> Connection::sendSyncMessage(uint64_t syncRequest
 
     ++m_inSendSyncCount;
 
+    auto token = MessageRecorder::recordOutgoingMessage(*this, *encoder);
+
     // First send the message.
-    sendMessage(WTF::move(encoder), DispatchMessageEvenWhenWaitingForSyncReply);
+    sendMessage(WTF::move(encoder), DispatchMessageEvenWhenWaitingForSyncReply, true);
 
     // Then wait for a reply. Waiting for a reply could involve dispatching incoming sync messages, so
     // keep an extra reference to the connection here in case it's invalidated.
@@ -515,7 +521,9 @@ std::unique_ptr<MessageDecoder> Connection::sendSyncMessageFromSecondaryThread(u
         m_secondaryThreadPendingSyncReplyMap.add(syncRequestID, &pendingReply);
     }
 
-    sendMessage(WTF::move(encoder), 0);
+    auto token = MessageRecorder::recordOutgoingMessage(*this, *encoder);
+
+    sendMessage(WTF::move(encoder), 0, true);
 
     pendingReply.semaphore.wait(currentTime() + (timeout.count() / 1000.0));
 
@@ -768,7 +776,7 @@ void Connection::dispatchSyncMessage(MessageDecoder& decoder)
         return;
     }
 
-    auto replyEncoder = std::make_unique<MessageEncoder>("IPC", "SyncMessageReply", syncRequestID);
+    auto replyEncoder = std::make_unique<MessageEncoder>("IPC", "SyncMessageReply", syncRequestID, decoder.UUID());
 
     // Hand off both the decoder and encoder to the client.
     m_client->didReceiveSyncMessage(*this, decoder, replyEncoder);
@@ -815,6 +823,8 @@ void Connection::dispatchMessage(MessageDecoder& decoder)
 
 void Connection::dispatchMessage(std::unique_ptr<MessageDecoder> message)
 {
+    MessageRecorder::recordIncomingMessage(*this, *message);
+
     if (!m_client)
         return;
 
index 156fff6c76b37a2f55bf354b93583a57e76b6b70..2b6fd0972f22642b9b4a850ea9e8ce7c9c6a3b3f 100644 (file)
@@ -32,6 +32,7 @@
 #include "MessageDecoder.h"
 #include "MessageEncoder.h"
 #include "MessageReceiver.h"
+#include "ProcessType.h"
 #include "WorkQueue.h"
 #include <atomic>
 #include <condition_variable>
@@ -90,6 +91,8 @@ public:
     public:
         virtual void didClose(Connection&) = 0;
         virtual void didReceiveInvalidMessage(Connection&, StringReference messageReceiverName, StringReference messageName) = 0;
+        virtual IPC::ProcessType localProcessType() = 0;
+        virtual IPC::ProcessType remoteProcessType() = 0;
 
     protected:
         virtual ~Client() { }
@@ -120,8 +123,9 @@ public:
         OSObjectPtr<xpc_connection_t> xpcConnection;
     };
     static bool identifierIsNull(Identifier identifier) { return identifier.port == MACH_PORT_NULL; }
-    xpc_connection_t xpcConnection() { return m_xpcConnection.get(); }
+    xpc_connection_t xpcConnection() const { return m_xpcConnection.get(); }
     bool getAuditToken(audit_token_t&);
+    pid_t remoteProcessID() const;
 #elif USE(UNIX_DOMAIN_SOCKETS)
     typedef int Identifier;
     static bool identifierIsNull(Identifier identifier) { return !identifier; }
@@ -174,7 +178,7 @@ public:
     template<typename T> bool waitForAndDispatchImmediately(uint64_t destinationID, std::chrono::milliseconds timeout, unsigned waitForMessageFlags = 0);
 
     std::unique_ptr<MessageEncoder> createSyncMessageEncoder(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID, uint64_t& syncRequestID);
-    bool sendMessage(std::unique_ptr<MessageEncoder>, unsigned messageSendFlags = 0);
+    bool sendMessage(std::unique_ptr<MessageEncoder>, unsigned messageSendFlags = 0, bool alreadyRecordedMessage = false);
     std::unique_ptr<MessageDecoder> sendSyncMessage(uint64_t syncRequestID, std::unique_ptr<MessageEncoder>, std::chrono::milliseconds timeout, unsigned syncSendFlags = 0);
     std::unique_ptr<MessageDecoder> sendSyncMessageFromSecondaryThread(uint64_t syncRequestID, std::unique_ptr<MessageEncoder>, std::chrono::milliseconds timeout);
     bool sendSyncReply(std::unique_ptr<MessageEncoder>);
@@ -193,13 +197,13 @@ public:
     void terminateSoon(double intervalInSeconds);
 #endif
 
+    bool isValid() const { return m_client; }
+
 private:
     Connection(Identifier, bool isServer, Client&, WTF::RunLoop& clientRunLoop);
     void platformInitialize(Identifier);
     void platformInvalidate();
     
-    bool isValid() const { return m_client; }
-    
     std::unique_ptr<MessageDecoder> waitForMessage(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID, std::chrono::milliseconds timeout, unsigned waitForMessageFlags);
     
     std::unique_ptr<MessageDecoder> waitForSyncReply(uint64_t syncRequestID, std::chrono::milliseconds timeout, unsigned syncSendFlags);
index 29a054ef0029128d413b22e79727be80110deacf..ff521c3134bced45176a1389a303339ee0228317 100644 (file)
@@ -53,7 +53,10 @@ MessageDecoder::MessageDecoder(const DataReference& buffer, Vector<Attachment> a
     if (!decode(m_messageName))
         return;
 
-    decode(m_destinationID);
+    if (!decode(m_destinationID))
+        return;
+
+    decode(m_UUID);
 }
 
 bool MessageDecoder::isSyncMessage() const
index eaa9b5e1017bf32d0fa33357f67530ea5734c28e..3fafad1472d5bb19744e19a0b7181702e634784a 100644 (file)
@@ -27,7 +27,9 @@
 #define MessageDecoder_h
 
 #include "ArgumentDecoder.h"
+#include "MessageRecorder.h"
 #include "StringReference.h"
+#include <uuid/uuid.h>
 
 namespace IPC {
 
@@ -50,6 +52,10 @@ public:
     void setImportanceAssertion(std::unique_ptr<ImportanceAssertion>);
 #endif
 
+    void setMessageProcessingToken(std::unique_ptr<MessageRecorder::MessageProcessingToken> token) { m_processingToken = WTF::move(token); }
+
+    const uuid_t& UUID() const { return m_UUID; }
+
 private:
     uint8_t m_messageFlags;
     StringReference m_messageReceiverName;
@@ -57,9 +63,13 @@ private:
 
     uint64_t m_destinationID;
 
+    uuid_t m_UUID;
+
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
     std::unique_ptr<ImportanceAssertion> m_importanceAssertion;
 #endif
+
+    std::unique_ptr<MessageRecorder::MessageProcessingToken> m_processingToken;
 };
 
 } // namespace IPC
index d2e4efe9a9bac4ec5965fb47156c694dbcd04bfd..bf7c3677b89d531a2facbb6f73cb2bda66230bd8 100644 (file)
 
 #include "ArgumentCoders.h"
 #include "MessageFlags.h"
+#include "MessageRecorder.h"
 #include "StringReference.h"
 
 namespace IPC {
 
 static uint8_t defaultMessageFlags = 0;
 
+MessageEncoder::MessageEncoder(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID, const uuid_t& UUID)
+    : m_messageReceiverName(messageReceiverName)
+    , m_messageName(messageName)
+    , m_destinationID(destinationID)
+{
+    uuid_copy(m_UUID, UUID);
+    encodeHeader();
+}
+
 MessageEncoder::MessageEncoder(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID)
+    : m_messageReceiverName(messageReceiverName)
+    , m_messageName(messageName)
+    , m_destinationID(destinationID)
+{
+    uuid_generate(m_UUID);
+    encodeHeader();
+}
+
+MessageEncoder::~MessageEncoder()
 {
-    ASSERT(!messageReceiverName.isEmpty());
+}
+
+void MessageEncoder::encodeHeader()
+{
+    ASSERT(!m_messageReceiverName.isEmpty());
 
     *this << defaultMessageFlags;
-    *this << messageReceiverName;
-    *this << messageName;
-    *this << destinationID;
+    *this << m_messageReceiverName;
+    *this << m_messageName;
+    *this << m_destinationID;
+    *this << m_UUID;
 }
 
-MessageEncoder::~MessageEncoder()
+bool MessageEncoder::isSyncMessage() const
+{
+    return *buffer() & SyncMessage;
+}
+
+bool MessageEncoder::shouldDispatchMessageWhenWaitingForSyncReply() const
 {
+    return *buffer() & DispatchMessageWhenWaitingForSyncReply;
 }
 
 void MessageEncoder::setIsSyncMessage(bool isSyncMessage)
index 524e5e1d43c7030187199c16f4d961f10ad3854c..872f264e27024b50364f0f5cf515de544b5c11eb 100644 (file)
@@ -27,6 +27,8 @@
 #define MessageEncoder_h
 
 #include "ArgumentEncoder.h"
+#include "StringReference.h"
+#include <uuid/uuid.h>
 #include <wtf/Forward.h>
 
 namespace IPC {
@@ -36,10 +38,28 @@ class StringReference;
 class MessageEncoder : public ArgumentEncoder {
 public:
     MessageEncoder(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID);
+    MessageEncoder(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID, const uuid_t&);
     virtual ~MessageEncoder();
 
+    StringReference messageReceiverName() const { return m_messageReceiverName; }
+    StringReference messageName() const { return m_messageName; }
+    uint64_t destinationID() const { return m_destinationID; }
+
     void setIsSyncMessage(bool);
+    bool isSyncMessage() const;
+
     void setShouldDispatchMessageWhenWaitingForSyncReply(bool);
+    bool shouldDispatchMessageWhenWaitingForSyncReply() const;
+
+    const uuid_t& UUID() const { return m_UUID; }
+
+private:
+    void encodeHeader();
+
+    StringReference m_messageReceiverName;
+    StringReference m_messageName;
+    uint64_t m_destinationID;
+    uuid_t m_UUID;
 };
 
 } // namespace IPC
diff --git a/Source/WebKit2/Platform/IPC/MessageRecorder.cpp b/Source/WebKit2/Platform/IPC/MessageRecorder.cpp
new file mode 100644 (file)
index 0000000..1b2e9c3
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MessageRecorder.h"
+
+#include "Connection.h"
+#include "MessageDecoder.h"
+#include "MessageEncoder.h"
+#include "MessageRecorderProbes.h"
+#include <wtf/CurrentTime.h>
+
+namespace IPC {
+
+bool MessageRecorder::isEnabled()
+{
+    return WEBKITMESSAGERECORDER_MESSAGE_RECEIVED_ENABLED() || WEBKITMESSAGERECORDER_MESSAGE_SENT_ENABLED();
+}
+
+std::unique_ptr<MessageRecorder::MessageProcessingToken> MessageRecorder::recordOutgoingMessage(Connection& connection, MessageEncoder& encoder)
+{
+    if (!isEnabled() || !connection.isValid())
+        return nullptr;
+
+    WebKitMessageRecord record;
+    record.sourceProcessType = static_cast<uint64_t>(connection.client()->localProcessType());
+    record.destinationProcessType = static_cast<uint64_t>(connection.client()->remoteProcessType());
+    record.destinationID = encoder.destinationID();
+    record.isSyncMessage = encoder.isSyncMessage();
+    record.shouldDispatchMessageWhenWaitingForSyncReply = encoder.shouldDispatchMessageWhenWaitingForSyncReply();
+    record.sourceProcessID = getpid();
+    record.destinationProcessID = connection.remoteProcessID();
+    record.isIncoming = false;
+
+    record.messageReceiverName = MallocPtr<char>::malloc(sizeof(char) * (encoder.messageReceiverName().size() + 1));
+    strncpy(record.messageReceiverName.get(), encoder.messageReceiverName().data(), encoder.messageReceiverName().size());
+    record.messageReceiverName.get()[encoder.messageReceiverName().size()] = 0;
+
+    record.messageName = MallocPtr<char>::malloc(sizeof(char) * (encoder.messageName().size() + 1));
+    strncpy(record.messageName.get(), encoder.messageName().data(), encoder.messageName().size());
+    record.messageName.get()[encoder.messageName().size()] = 0;
+
+    uuid_copy(record.UUID, encoder.UUID());
+
+    return std::make_unique<MessageProcessingToken>(WTF::move(record));
+}
+
+void MessageRecorder::recordIncomingMessage(Connection& connection, MessageDecoder& decoder)
+{
+    if (!isEnabled() || !connection.isValid())
+        return;
+
+    WebKitMessageRecord record;
+    record.sourceProcessType = static_cast<uint64_t>(connection.client()->remoteProcessType());
+    record.destinationProcessType = static_cast<uint64_t>(connection.client()->localProcessType());
+    record.destinationID = decoder.destinationID();
+    record.isSyncMessage = decoder.isSyncMessage();
+    record.shouldDispatchMessageWhenWaitingForSyncReply = decoder.shouldDispatchMessageWhenWaitingForSyncReply();
+    record.sourceProcessID = connection.remoteProcessID();
+    record.destinationProcessID = getpid();
+    record.isIncoming = true;
+
+    record.messageReceiverName = MallocPtr<char>::malloc(sizeof(char) * (decoder.messageReceiverName().size() + 1));
+    strncpy(record.messageReceiverName.get(), decoder.messageReceiverName().data(), decoder.messageReceiverName().size());
+    record.messageReceiverName.get()[decoder.messageReceiverName().size()] = 0;
+
+    record.messageName = MallocPtr<char>::malloc(sizeof(char) * (decoder.messageName().size() + 1));
+    strncpy(record.messageName.get(), decoder.messageName().data(), decoder.messageName().size());
+    record.messageName.get()[decoder.messageName().size()] = 0;
+
+    uuid_copy(record.UUID, decoder.UUID());
+
+    decoder.setMessageProcessingToken(std::make_unique<MessageProcessingToken>(WTF::move(record)));
+}
+
+#pragma mark MessageProcessingToken
+
+MessageRecorder::MessageProcessingToken::MessageProcessingToken(WebKitMessageRecord record)
+    : m_record(WTF::move(record))
+{
+    m_record.startTime = monotonicallyIncreasingTime();
+}
+
+MessageRecorder::MessageProcessingToken::~MessageProcessingToken()
+{
+    m_record.endTime = monotonicallyIncreasingTime();
+
+    if (m_record.isIncoming)
+        WEBKITMESSAGERECORDER_MESSAGE_RECEIVED(&m_record);
+    else
+        WEBKITMESSAGERECORDER_MESSAGE_SENT(&m_record);
+}
+
+}
diff --git a/Source/WebKit2/Platform/IPC/MessageRecorder.h b/Source/WebKit2/Platform/IPC/MessageRecorder.h
new file mode 100644 (file)
index 0000000..a25b39c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MessageRecorder_h
+#define MessageRecorder_h
+
+#include "ProcessType.h"
+#include <uuid/uuid.h>
+#include <wtf/Forward.h>
+#include <wtf/MallocPtr.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+struct WebKitMessageRecord {
+    uint8_t sourceProcessType; // IPC::ProcessType
+    pid_t sourceProcessID;
+
+    uint8_t destinationProcessType; // IPC::ProcessType
+    pid_t destinationProcessID;
+
+    MallocPtr<char> messageReceiverName;
+    MallocPtr<char> messageName;
+    uint64_t destinationID;
+
+    uuid_t UUID;
+
+    double startTime;
+    double endTime;
+
+    bool isSyncMessage;
+    bool shouldDispatchMessageWhenWaitingForSyncReply;
+    bool isIncoming;
+};
+
+namespace IPC {
+
+class Connection;
+class MessageDecoder;
+class MessageEncoder;
+
+class MessageRecorder {
+public:
+    static bool isEnabled();
+
+    class MessageProcessingToken {
+        WTF_MAKE_NONCOPYABLE(MessageProcessingToken);
+    public:
+        explicit MessageProcessingToken(WebKitMessageRecord);
+        ~MessageProcessingToken();
+
+    private:
+        WebKitMessageRecord m_record;
+    };
+
+    static std::unique_ptr<MessageRecorder::MessageProcessingToken> recordOutgoingMessage(IPC::Connection&, IPC::MessageEncoder&);
+    static void recordIncomingMessage(IPC::Connection&, IPC::MessageDecoder&);
+
+private:
+    explicit MessageRecorder() { }
+};
+
+};
+
+#endif // MessageRecorder_h
diff --git a/Source/WebKit2/Platform/IPC/MessageRecorderProbes.d b/Source/WebKit2/Platform/IPC/MessageRecorderProbes.d
new file mode 100644 (file)
index 0000000..f57e293
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct WebKitMessageRecord;
+
+provider WebKitMessageRecorder {
+    probe message_sent(struct WebKitMessageRecord*);
+    probe message_received(struct WebKitMessageRecord*);
+};
diff --git a/Source/WebKit2/Platform/IPC/ProcessType.h b/Source/WebKit2/Platform/IPC/ProcessType.h
new file mode 100644 (file)
index 0000000..237c267
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProcessType_h
+#define ProcessType_h
+
+namespace IPC {
+
+enum class ProcessType : uint8_t {
+    UI,
+    Web,
+    Network,
+    Database,
+    Plugin
+};
+
+};
+
+#endif
index 57c9f20d8bc1527437914049f9e9017d576b99c2..b83168f9a9210a93e8196272de5b868d888a2705 100644 (file)
@@ -609,6 +609,14 @@ void Connection::didReceiveSyncReply(unsigned flags)
     if ((flags & InformPlatformProcessWillSuspend) && WebCore::AXObjectCache::accessibilityEnabled())
         _AXUIElementNotifyProcessSuspendStatus(AXSuspendStatusRunning);
 #endif
-}    
+}
+
+pid_t Connection::remoteProcessID() const
+{
+    if (!m_xpcConnection)
+        return 0;
+
+    return xpc_connection_get_pid(m_xpcConnection.get());
+}
     
 } // namespace IPC
index 3df2d825369d0e84f1a7c013c0bad1a2ab1807d7..3568d09aef8f9114c1f1b7fb2f6727947c18f6f4 100644 (file)
@@ -91,6 +91,8 @@ private:
     virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Plugin; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::UI; }
 
     // Message handlers.
     void didReceivePluginProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
index 6d550eeff7278ebcab9de2da1d6afb8880467e62..1221f959d23b7acb515ba47f0c942fea6b1025f7 100644 (file)
@@ -69,6 +69,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Plugin; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Web; }
 
     // Message handlers.
     void didReceiveWebProcessConnectionMessage(IPC::Connection&, IPC::MessageDecoder&);
index a7b981024140dc8b43cc84bf4f39ebbff53fe613..be66adedee277da4579cc8ee72bb82cd9a8b56eb 100644 (file)
@@ -54,6 +54,8 @@ private:
     virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::UI; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Database; }
 
     void didReceiveDatabaseProcessProxyMessage(IPC::Connection&, IPC::MessageDecoder&);
 
index 35f264ad542c710aac8bd27569bd66d8ab611153..cd996d1b6ddcae77d16fe8e99b119d439fb7b017 100644 (file)
@@ -83,6 +83,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::UI; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Network; }
 
     // Message handlers
     void didReceiveNetworkProcessProxyMessage(IPC::Connection&, IPC::MessageDecoder&);
index d6f700a73e4eca62f36d4f11a880bfe89de338ea..45feedd8271422a6822639096c9a166d656f7593 100644 (file)
@@ -120,6 +120,8 @@ private:
 
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::UI; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Plugin; }
 
     // ProcessLauncher::Client
     virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
index 1b65b287e9dea43f8d35a498bbcb0c5ae03f10eb..5760ddd2cfbe282b83ddb2d8e2e468acf191b4cf 100644 (file)
@@ -184,6 +184,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::UI; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Web; }
 
     // ResponsivenessTimer::Client
     void didBecomeUnresponsive(ResponsivenessTimer*) override;
index 01236f84fa116a129cea9b65c4720537c0056dfe..6c4cef62aeb27af588777d038e5dca665f07e788 100644 (file)
                2D429BFD1721E2C700EC681F /* PDFPluginPasswordField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D429BFB1721E2BA00EC681F /* PDFPluginPasswordField.mm */; };
                2D47B56C1810714E003A3AEE /* RemoteLayerBackingStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D47B56A1810714E003A3AEE /* RemoteLayerBackingStore.mm */; };
                2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D47B56B1810714E003A3AEE /* RemoteLayerBackingStore.h */; };
+               2D5AB62E1A69D6FB0014A9CB /* MessageRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5AB62B1A69D6FB0014A9CB /* MessageRecorder.h */; };
+               2D5AB62F1A69D6FB0014A9CB /* MessageRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D5AB62C1A69D6FB0014A9CB /* MessageRecorder.cpp */; };
+               2D5AB6301A69D6FB0014A9CB /* MessageRecorderProbes.d in Sources */ = {isa = PBXBuildFile; fileRef = 2D5AB62D1A69D6FB0014A9CB /* MessageRecorderProbes.d */; };
                2D5C9D0519C81D8F00B3C5C1 /* WebPageOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D5C9D0319C81D8F00B3C5C1 /* WebPageOverlay.cpp */; };
                2D5C9D0619C81D8F00B3C5C1 /* WebPageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5C9D0419C81D8F00B3C5C1 /* WebPageOverlay.h */; };
                2D6AB541192B1C4A003A9FD1 /* WKPDFPageNumberIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D6AB53F192B1C4A003A9FD1 /* WKPDFPageNumberIndicator.h */; };
                2D6CD11A189058A500E5A4A0 /* ViewSnapshotStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D6CD118189058A500E5A4A0 /* ViewSnapshotStore.mm */; };
                2D7AAFD318C8640600A7ACD4 /* WKWebViewContentProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7AAFD218C8640600A7ACD4 /* WKWebViewContentProvider.h */; };
                2D7AAFD618C956AF00A7ACD4 /* WKWebViewConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7AAFD518C956AF00A7ACD4 /* WKWebViewConfigurationInternal.h */; };
+               2D7F13101A702FBA009A6FBD /* ProcessType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7F130F1A702FBA009A6FBD /* ProcessType.h */; };
                2D819B9E18627EE9001F03D1 /* ViewGestureGeometryCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D819B99186275B3001F03D1 /* ViewGestureGeometryCollector.cpp */; };
                2D819BA11862800E001F03D1 /* ViewGestureGeometryCollectorMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D819B9F1862800E001F03D1 /* ViewGestureGeometryCollectorMessageReceiver.cpp */; };
                2D819BA21862800E001F03D1 /* ViewGestureGeometryCollectorMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D819BA01862800E001F03D1 /* ViewGestureGeometryCollectorMessages.h */; };
                2D429BFB1721E2BA00EC681F /* PDFPluginPasswordField.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPluginPasswordField.mm; path = PDF/PDFPluginPasswordField.mm; sourceTree = "<group>"; };
                2D47B56A1810714E003A3AEE /* RemoteLayerBackingStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteLayerBackingStore.mm; sourceTree = "<group>"; };
                2D47B56B1810714E003A3AEE /* RemoteLayerBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteLayerBackingStore.h; sourceTree = "<group>"; };
+               2D5AB62B1A69D6FB0014A9CB /* MessageRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageRecorder.h; sourceTree = "<group>"; };
+               2D5AB62C1A69D6FB0014A9CB /* MessageRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageRecorder.cpp; sourceTree = "<group>"; };
+               2D5AB62D1A69D6FB0014A9CB /* MessageRecorderProbes.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = MessageRecorderProbes.d; sourceTree = "<group>"; };
                2D5C9D0319C81D8F00B3C5C1 /* WebPageOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPageOverlay.cpp; sourceTree = "<group>"; };
                2D5C9D0419C81D8F00B3C5C1 /* WebPageOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageOverlay.h; sourceTree = "<group>"; };
                2D6AB53F192B1C4A003A9FD1 /* WKPDFPageNumberIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKPDFPageNumberIndicator.h; path = ios/WKPDFPageNumberIndicator.h; sourceTree = "<group>"; };
                2D70AB1418A1D57C00026D6E /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = "<group>"; };
                2D7AAFD218C8640600A7ACD4 /* WKWebViewContentProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewContentProvider.h; sourceTree = "<group>"; };
                2D7AAFD518C956AF00A7ACD4 /* WKWebViewConfigurationInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewConfigurationInternal.h; sourceTree = "<group>"; };
+               2D7F130F1A702FBA009A6FBD /* ProcessType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessType.h; sourceTree = "<group>"; };
                2D819B99186275B3001F03D1 /* ViewGestureGeometryCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ViewGestureGeometryCollector.cpp; sourceTree = "<group>"; };
                2D819B9A186275B3001F03D1 /* ViewGestureGeometryCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewGestureGeometryCollector.h; sourceTree = "<group>"; };
                2D819B9B186275B3001F03D1 /* ViewGestureGeometryCollector.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ViewGestureGeometryCollector.messages.in; sourceTree = "<group>"; };
                                1A3EED11161A53D600AEB4F5 /* MessageReceiver.h */,
                                1A3EED0C161A535300AEB4F5 /* MessageReceiverMap.cpp */,
                                1A3EED0D161A535300AEB4F5 /* MessageReceiverMap.h */,
+                               2D5AB62B1A69D6FB0014A9CB /* MessageRecorder.h */,
+                               2D5AB62C1A69D6FB0014A9CB /* MessageRecorder.cpp */,
+                               2D5AB62D1A69D6FB0014A9CB /* MessageRecorderProbes.d */,
                                1AAB0377185A7C6A00EDF501 /* MessageSender.cpp */,
                                1AAB0378185A7C6A00EDF501 /* MessageSender.h */,
+                               2D7F130F1A702FBA009A6FBD /* ProcessType.h */,
                                1AE00D6918327C1200087DD7 /* StringReference.cpp */,
                                1AE00D6A18327C1200087DD7 /* StringReference.h */,
                        );
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               2D7F13101A702FBA009A6FBD /* ProcessType.h in Headers */,
                                37A5E01418BBF93F000A081E /* _WKActivatedElementInfo.h in Headers */,
                                379A873618BBFA4300588AF2 /* _WKActivatedElementInfoInternal.h in Headers */,
                                A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */,
                                1AA56F2911E92BC80061B882 /* PluginController.h in Headers */,
                                1A8EF4CB1252403700F7067F /* PluginControllerProxy.h in Headers */,
                                1A8EF96F1252AF6B00F7067F /* PluginControllerProxyMessages.h in Headers */,
+                               2D5AB62E1A69D6FB0014A9CB /* MessageRecorder.h in Headers */,
                                1A179780137EE82C00F97D45 /* PluginCreationParameters.h in Headers */,
                                7C3F8C91173AF52D007B7F39 /* PluginInformation.h in Headers */,
                                7C89D2B41A6B068C003A5FDE /* APIUserContentFilter.h in Headers */,
                                1AFDE6591954A42B00C48FFA /* SessionState.cpp in Sources */,
                                1A002D48196B345D00B9AD44 /* SessionStateCoding.mm in Sources */,
                                1A7284481959F8040007BCE5 /* SessionStateConversion.cpp in Sources */,
+                               2D5AB6301A69D6FB0014A9CB /* MessageRecorderProbes.d in Sources */,
                                753E3E0D1887398500188496 /* SessionTracker.cpp in Sources */,
                                1A6420E412DCE2FF00CAAE2C /* ShareableBitmap.cpp in Sources */,
                                C01A260112662F2100C9ED55 /* ShareableBitmapCG.cpp in Sources */,
                                BC111B5E112F629800337BAB /* WebEventFactory.mm in Sources */,
                                1A3DD1FD125E59F3004515E6 /* WebFindClient.cpp in Sources */,
                                BCE469531214E6CB000B98EB /* WebFormClient.cpp in Sources */,
+                               2D5AB62F1A69D6FB0014A9CB /* MessageRecorder.cpp in Sources */,
                                BCE469551214E6CB000B98EB /* WebFormSubmissionListenerProxy.cpp in Sources */,
                                BC111ADD112F5B9300337BAB /* WebFrame.cpp in Sources */,
                                BCE469791214F2B4000B98EB /* WebFrameListenerProxy.cpp in Sources */,
index df231669a3a99011f9f9444a508ed8aff6abe8b3..ef5bfc93315b37cf92f6cf218bb74039adf1bb54 100644 (file)
@@ -58,6 +58,8 @@ private:
     virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Database; }
 
     // IPC::MessageSender
     virtual IPC::Connection* messageSenderConnection() override { return m_connection.get(); }
index 1602705e176edf74d015ff6e34629bc326409bfa..803e8010d95c66ecf1071795d7a7ed9d92457911 100644 (file)
@@ -68,6 +68,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Network; }
 
 #if ENABLE(SHAREABLE_RESOURCE)
     // Message handlers.
index 15aced6a813899e73d42148bc80f34d57f0f6202..4361030065689a2f63096ecb54b5933857254fc8 100644 (file)
@@ -68,6 +68,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Plugin; }
 
     // Message handlers.
     void didReceivePluginProcessConnectionMessage(IPC::Connection&, IPC::MessageDecoder&);
index 155d671ac4fde6b285cdbae4e07a7d4c5340476d..ed85c909b292aafa9c943fec4a4e4e1b4425bc29 100644 (file)
@@ -53,6 +53,8 @@ public:
     // IPC::Connection::Client
     void didClose(IPC::Connection&) override { close(); }
     void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) override { close(); }
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::UI; }
 
     // Called by WebInspector messages
     void connectionEstablished();
index 8bef1772f322f2b90d940b673fb2c910ac5e2e38..f835fcaf873913c8a9c9e8dca1c68de306eecd1f 100644 (file)
@@ -48,6 +48,8 @@ public:
     // IPC::Connection::Client
     void didClose(IPC::Connection&) override { closeWindow(); }
     void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) override { closeWindow(); }
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Web; }
 
     // Called by WebInspectorUI messages
     void establishConnection(IPC::Attachment connectionIdentifier, uint64_t inspectedPageIdentifier, bool underTest);
index f2e721f468b15ea1d64aa1be340445b71c377623..df94ee74d93a86eb46c3d06370bfad44177763b3 100644 (file)
@@ -290,6 +290,8 @@ private:
     virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
     virtual void didClose(IPC::Connection&) override;
     virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
+    virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; }
+    virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::UI; }
 
     // Implemented in generated WebProcessMessageReceiver.cpp
     void didReceiveWebProcessMessage(IPC::Connection&, IPC::MessageDecoder&);
index dbed956227457a78941c43de55839c0ce0708e78..72df1ce5b1fad236ac8f5e4b0f5e1af03571f62a 100644 (file)
@@ -1,3 +1,13 @@
+2015-01-28  Timothy Horton  <timothy_horton@apple.com>
+
+        Add a WebKitMessageRecorder DTrace provider, exposing IPC details to DTrace
+        https://bugs.webkit.org/show_bug.cgi?id=140673
+
+        Reviewed by Sam Weinig.
+
+        * Scripts/dtrace/trace-webkit2-messages.d: Added.
+        Add a DTrace script that outputs a small blob of JSON per message.
+
 2015-01-28  Geoffrey Garen  <ggaren@apple.com>
 
         Removed fastMallocForbid / fastMallocAllow
diff --git a/Tools/Scripts/dtrace/trace-webkit2-messages.d b/Tools/Scripts/dtrace/trace-webkit2-messages.d
new file mode 100755 (executable)
index 0000000..4e8911d
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/sbin/dtrace -qZs
+
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct WebKitMessageRecord {
+    uint8_t sourceProcessType;
+    pid_t sourceProcessID;
+
+    uint8_t destinationProcessType;
+    pid_t destinationProcessID;
+
+    char* messageReceiverName;
+    char* messageName;
+    uint64_t destinationID;
+
+    char UUID[16];
+
+    double startTime;
+    double endTime;
+
+    bool isSyncMessage;
+    bool shouldDispatchMessageWhenWaitingForSyncReply;
+    bool isIncoming;
+};
+
+WebKitMessageRecorder*:::message_*
+{
+    this->record = (struct WebKitMessageRecord*)copyin(arg0, sizeof(struct WebKitMessageRecord));
+    printf("{");
+
+    printf("\"sourceProcessType\": %d, ", this->record->sourceProcessType);
+    printf("\"sourceProcessID\": %d, ", this->record->sourceProcessID);
+
+    printf("\"destinationProcessType\": %d, ", this->record->destinationProcessType);
+    printf("\"destinationProcessID\": %d, ", this->record->destinationProcessID);
+
+    printf("\"messageReceiverName\": \"%s\", ", copyinstr((user_addr_t)this->record->messageReceiverName));
+    printf("\"messageName\": \"%s\", ", copyinstr((user_addr_t)this->record->messageName));
+
+    printf("\"destinationID\": %d, ", this->record->destinationID);
+
+    printf("\"UUID\": \"");
+    printf("%02x", this->record->UUID[0]);
+    printf("%02x", this->record->UUID[1]);
+    printf("%02x", this->record->UUID[2]);
+    printf("%02x", this->record->UUID[3]);
+    printf("-");
+    printf("%02x", this->record->UUID[4]);
+    printf("%02x", this->record->UUID[5]);
+    printf("-");
+    printf("%02x", this->record->UUID[6]);
+    printf("%02x", this->record->UUID[7]);
+    printf("-");
+    printf("%02x", this->record->UUID[8]);
+    printf("%02x", this->record->UUID[9]);
+    printf("-");
+    printf("%02x", this->record->UUID[10]);
+    printf("%02x", this->record->UUID[11]);
+    printf("%02x", this->record->UUID[12]);
+    printf("%02x", this->record->UUID[13]);
+    printf("%02x", this->record->UUID[14]);
+    printf("%02x", this->record->UUID[15]);
+    printf("\", ");
+
+    printf("\"startTime\": %f, ", this->record->startTime);
+    printf("\"endTime\": %f, ", this->record->endTime);
+
+    printf("\"isSyncMessage\": %d, ", this->record->isSyncMessage);
+    printf("\"shouldDispatchMessageWhenWaitingForSyncReply\": %d, ", this->record->shouldDispatchMessageWhenWaitingForSyncReply);
+    printf("\"isIncoming\": %d", this->record->isIncoming);
+
+    printf("}\n");
+}