[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e

andersca at apple.com andersca at apple.com
Fri Jan 21 14:35:45 UTC 2011


The following commit has been merged in the debian/experimental branch:
commit 98dbdadb1bbc8f9096432e06b7bf4af95013338b
Author: andersca at apple.com <andersca at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 23 00:15:24 2010 +0000

    2010-12-22  Anders Carlsson  <andersca at apple.com>
    
            Reviewed by Darin Adler.
    
            Detect WebProcess crashes sooner, without waiting for ReportCrash to finish
            https://bugs.webkit.org/show_bug.cgi?id=51505
    
            * Platform/CoreIPC/CoreIPCMessageKinds.h:
            Add SetExceptionPort.
    
            * Platform/CoreIPC/mac/ConnectionMac.cpp:
            (CoreIPC::Connection::platformInvalidate):
            If we have an exception port, unregister it.
    
            (CoreIPC::Connection::platformInitialize):
            Set m_exceptionPort to null.
    
            (CoreIPC::Connection::open):
            If we have an exception port, register an event handler for it and send it over
            to the other side.
    
            (CoreIPC::Connection::receiveSourceEventHandler):
            Handle the SetExceptionPort message.
    
            (CoreIPC::Connection::exceptionSourceEventHandler):
            Receive the message, forward it to the real exception handler and call connectionDidClose.
    
            (CoreIPC::Connection::setShouldCloseConnectionOnMachExceptions):
            Create an exception port.
    
            * Platform/mac/MachUtilities.cpp:
            (machExceptionPort):
            (setMachExceptionPort):
            * Platform/mac/MachUtilities.h:
            Add helper functions for getting and setting the mach exception port.
    
            * UIProcess/WebProcessProxy.cpp:
            (WebKit::WebProcessProxy::didFinishLaunching):
            Call setShouldCloseConnectionOnMachExceptions on Mac.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74514 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index 5c23133..3408dbb 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,5 +1,45 @@
 2010-12-22  Anders Carlsson  <andersca at apple.com>
 
+        Reviewed by Darin Adler.
+
+        Detect WebProcess crashes sooner, without waiting for ReportCrash to finish
+        https://bugs.webkit.org/show_bug.cgi?id=51505
+
+        * Platform/CoreIPC/CoreIPCMessageKinds.h:
+        Add SetExceptionPort.
+
+        * Platform/CoreIPC/mac/ConnectionMac.cpp:
+        (CoreIPC::Connection::platformInvalidate):
+        If we have an exception port, unregister it.
+
+        (CoreIPC::Connection::platformInitialize):
+        Set m_exceptionPort to null.
+
+        (CoreIPC::Connection::open):
+        If we have an exception port, register an event handler for it and send it over
+        to the other side.
+
+        (CoreIPC::Connection::receiveSourceEventHandler):
+        Handle the SetExceptionPort message.
+
+        (CoreIPC::Connection::exceptionSourceEventHandler):
+        Receive the message, forward it to the real exception handler and call connectionDidClose.
+
+        (CoreIPC::Connection::setShouldCloseConnectionOnMachExceptions):
+        Create an exception port.
+
+        * Platform/mac/MachUtilities.cpp:
+        (machExceptionPort):
+        (setMachExceptionPort):
+        * Platform/mac/MachUtilities.h:
+        Add helper functions for getting and setting the mach exception port.
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::didFinishLaunching):
+        Call setShouldCloseConnectionOnMachExceptions on Mac.
+
+2010-12-22  Anders Carlsson  <andersca at apple.com>
+
         Reviewed by Sam Weinig.
 
         Move Mach message receiving code out into a new function
diff --git a/WebKit2/Platform/CoreIPC/Connection.h b/WebKit2/Platform/CoreIPC/Connection.h
index 4da2200..dfe7f82 100644
--- a/WebKit2/Platform/CoreIPC/Connection.h
+++ b/WebKit2/Platform/CoreIPC/Connection.h
@@ -99,6 +99,10 @@ public:
     static PassRefPtr<Connection> createClientConnection(Identifier, Client*, RunLoop* clientRunLoop);
     ~Connection();
 
+#if PLATFORM(MAC)
+    void setShouldCloseConnectionOnMachExceptions();
+#endif
+
     bool open();
     void invalidate();
 
@@ -245,9 +249,15 @@ private:
     // Called on the connection queue.
     void receiveSourceEventHandler();
     void initializeDeadNameSource();
+    void exceptionSourceEventHandler();
 
     mach_port_t m_sendPort;
     mach_port_t m_receivePort;
+
+    // If setShouldCloseConnectionOnMachExceptions has been called, this has
+    // the exception port that exceptions from the other end will be sent on.
+    mach_port_t m_exceptionPort;
+
 #elif PLATFORM(WIN)
     // Called on the connection queue.
     void readEventHandler();
diff --git a/WebKit2/Platform/CoreIPC/CoreIPCMessageKinds.h b/WebKit2/Platform/CoreIPC/CoreIPCMessageKinds.h
index a9380b4..b2a2813 100644
--- a/WebKit2/Platform/CoreIPC/CoreIPCMessageKinds.h
+++ b/WebKit2/Platform/CoreIPC/CoreIPCMessageKinds.h
@@ -35,6 +35,9 @@ namespace CoreIPCMessage {
 enum Kind {
     InitializeConnection,
     SyncMessageReply,
+#if PLATFORM(MAC)
+    SetExceptionPort,
+#endif
 };
 
 } // namespace CoreIPCMessage
diff --git a/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp b/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp
index 5a62d78..5e7bbbc 100644
--- a/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp
+++ b/WebKit2/Platform/CoreIPC/mac/ConnectionMac.cpp
@@ -50,17 +50,24 @@ void Connection::platformInvalidate()
 
     ASSERT(m_sendPort);
     ASSERT(m_receivePort);
-    
+
     // Unregister our ports.
     m_connectionQueue.unregisterMachPortEventHandler(m_sendPort);
     m_sendPort = MACH_PORT_NULL;
 
     m_connectionQueue.unregisterMachPortEventHandler(m_receivePort);
     m_receivePort = MACH_PORT_NULL;
+
+    if (m_exceptionPort) {
+        m_connectionQueue.unregisterMachPortEventHandler(m_exceptionPort);
+        m_exceptionPort = MACH_PORT_NULL;
+    }
 }
 
 void Connection::platformInitialize(Identifier identifier)
 {
+    m_exceptionPort = MACH_PORT_NULL;
+
     if (m_isServer) {
         m_receivePort = identifier;
         m_sendPort = MACH_PORT_NULL;
@@ -96,8 +103,14 @@ bool Connection::open()
     setMachPortQueueLength(m_receivePort, MACH_PORT_QLIMIT_LARGE);
 
     // Register the data available handler.
-    m_connectionQueue.registerMachPortEventHandler(m_receivePort, WorkQueue::MachPortDataAvailable, 
-                                                   WorkItem::create(this, &Connection::receiveSourceEventHandler));
+    m_connectionQueue.registerMachPortEventHandler(m_receivePort, WorkQueue::MachPortDataAvailable, WorkItem::create(this, &Connection::receiveSourceEventHandler));
+
+    // If we have an exception port, register the data available handler and send over the port to the other end.
+    if (m_exceptionPort) {
+        m_connectionQueue.registerMachPortEventHandler(m_exceptionPort, WorkQueue::MachPortDataAvailable, WorkItem::create(this, &Connection::exceptionSourceEventHandler));
+
+        send(CoreIPCMessage::SetExceptionPort, 0, MachPort(m_exceptionPort, MACH_MSG_TYPE_MAKE_SEND));
+    }
 
     return true;
 }
@@ -350,8 +363,62 @@ void Connection::receiveSourceEventHandler()
         
         return;
     }
-    
+
+    if (messageID == MessageID(CoreIPCMessage::SetExceptionPort)) {
+        MachPort exceptionPort;
+        if (!arguments->decode(exceptionPort))
+            return;
+
+        setMachExceptionPort(exceptionPort.port());
+        return;
+    }
+
     processIncomingMessage(messageID, arguments.release());
 }    
 
+void Connection::exceptionSourceEventHandler()
+{
+    ReceiveBuffer buffer;
+
+    mach_msg_header_t* header = readFromMachPort(m_exceptionPort, buffer);
+    if (!header)
+        return;
+
+    // We've read the exception message. Now send it on to the real exception port.
+
+    // The remote port should have a send once right.
+    ASSERT(MACH_MSGH_BITS_REMOTE(header->msgh_bits) == MACH_MSG_TYPE_MOVE_SEND_ONCE);
+
+    // Now get the real exception port.
+    mach_port_t exceptionPort = machExceptionPort();
+
+    // First, get the complex bit from the source message.
+    mach_msg_bits_t messageBits = header->msgh_bits & MACH_MSGH_BITS_COMPLEX;
+    messageBits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MOVE_SEND_ONCE);
+
+    header->msgh_bits = messageBits;
+    header->msgh_local_port = header->msgh_remote_port;
+    header->msgh_remote_port = exceptionPort;
+
+    // Now send along the message.
+    kern_return_t kr = mach_msg(header, MACH_SEND_MSG, header->msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+    if (kr != KERN_SUCCESS) {
+        LOG_ERROR("Failed to send message to real exception port, error %x", kr);
+        ASSERT_NOT_REACHED();
+    }
+
+    connectionDidClose();
+}
+
+void Connection::setShouldCloseConnectionOnMachExceptions()
+{
+    ASSERT(m_exceptionPort == MACH_PORT_NULL);
+
+    if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_exceptionPort) != KERN_SUCCESS)
+        ASSERT_NOT_REACHED();
+
+    if (mach_port_insert_right(mach_task_self(), m_exceptionPort, m_exceptionPort, MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS)
+        ASSERT_NOT_REACHED();
+}
+
 } // namespace CoreIPC
diff --git a/WebKit2/Platform/mac/MachUtilities.cpp b/WebKit2/Platform/mac/MachUtilities.cpp
index 9709376..6d5f246 100644
--- a/WebKit2/Platform/mac/MachUtilities.cpp
+++ b/WebKit2/Platform/mac/MachUtilities.cpp
@@ -32,3 +32,34 @@ void setMachPortQueueLength(mach_port_t receivePort, mach_port_msgcount_t queueL
 
     mach_port_set_attributes(mach_task_self(), receivePort, MACH_PORT_LIMITS_INFO, reinterpret_cast<mach_port_info_t>(&portLimits), MACH_PORT_LIMITS_INFO_COUNT);
 }
+
+mach_port_t machExceptionPort()
+{
+    exception_mask_t exceptionMasks[EXC_TYPES_COUNT];
+    exception_port_t exceptionHandlers[EXC_TYPES_COUNT];
+    exception_behavior_t exceptionBehaviors[EXC_TYPES_COUNT];
+    thread_state_flavor_t exceptionFlavors[EXC_TYPES_COUNT];
+    mach_msg_type_number_t numExceptionMasks;
+
+    kern_return_t kr = task_get_exception_ports(mach_task_self(), EXC_MASK_CRASH, exceptionMasks, &numExceptionMasks, exceptionHandlers, exceptionBehaviors, exceptionFlavors);
+    if (kr != KERN_SUCCESS) {
+        ASSERT_NOT_REACHED();
+        return MACH_PORT_NULL;
+    }
+
+    // We're just interested in the first exception handler.
+    return exceptionHandlers[0];
+}
+
+void setMachExceptionPort(mach_port_t exceptionPort)
+{
+    // Assert that we dont try to call setMachExceptionPort more than once per process.
+#if !ASSERT_DISABLED
+    static mach_port_t taskExceptionPort = MACH_PORT_NULL;
+    ASSERT(taskExceptionPort == MACH_PORT_NULL);
+    taskExceptionPort = exceptionPort;
+#endif
+
+    if (task_set_exception_ports(mach_task_self(), EXC_MASK_CRASH, exceptionPort, EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE) != KERN_SUCCESS)
+        ASSERT_NOT_REACHED();
+}
diff --git a/WebKit2/Platform/mac/MachUtilities.h b/WebKit2/Platform/mac/MachUtilities.h
index 05150cb..a8d0d6f 100644
--- a/WebKit2/Platform/mac/MachUtilities.h
+++ b/WebKit2/Platform/mac/MachUtilities.h
@@ -30,4 +30,7 @@
 
 void setMachPortQueueLength(mach_port_t, mach_port_msgcount_t queueLength);
 
+mach_port_t machExceptionPort();
+void setMachExceptionPort(mach_port_t exceptionPort);
+
 #endif // MachUtilities_h
diff --git a/WebKit2/UIProcess/WebProcessProxy.cpp b/WebKit2/UIProcess/WebProcessProxy.cpp
index c198b41..eed7213 100644
--- a/WebKit2/UIProcess/WebProcessProxy.cpp
+++ b/WebKit2/UIProcess/WebProcessProxy.cpp
@@ -323,6 +323,10 @@ void WebProcessProxy::didFinishLaunching(CoreIPC::Connection::Identifier connect
     ASSERT(!m_connection);
     
     m_connection = CoreIPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main());
+#if PLATFORM(MAC)
+    m_connection->setShouldCloseConnectionOnMachExceptions();
+#endif
+    
     m_connection->open();
     
     for (size_t i = 0; i < m_pendingMessages.size(); ++i) {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list