[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