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

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

<h3>Log Message</h3>
<pre>Cherry-pick <a href="http://trac.webkit.org/projects/webkit/changeset/285177">r285177</a>. rdar://problem/84987165

    Terminate unresponsive network process by crashing it
    https://bugs.webkit.org/show_bug.cgi?id=232603

    Reviewed by Chris Dumez.

    UI process currently kills network process when it does not respond message in some time (network process being
    unresponsive). We've found one common case where network process becomes unresponsive is that it is blocked by
    some slow operation on the main thread (like file operation in rdar://84511633). To understand what the
    operations are and make a fix, we now ask network process to crash itself on IPC thread. In this way, we can get
    crash report that includes the call stack of the main thread. To avoid generating too many crash reports, we
    only send the crash message to network process when it becomes unresponsive multiple times in a short time
    period.

    * Platform/IPC/Connection.cpp:
    (IPC::terminateDueToIPCTerminateMessage):
    (IPC::Connection::processIncomingMessage):
    * Scripts/webkit/model.py:
    * Scripts/webkit/tests/MessageNames.cpp:
    (IPC::description):
    (IPC::receiverName):
    (IPC::isValidMessageName):
    * Scripts/webkit/tests/MessageNames.h:
    * UIProcess/Network/NetworkProcessProxy.cpp:
    (WebKit::shouldTerminateNetworkProcessBySendingMessage):
    (WebKit::NetworkProcessProxy::didBecomeUnresponsive):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@285177 268f45cc-cd09-0410-ab3c-d52691b4dbfc</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari612331branchSourceWebKitChangeLog">branches/safari-612.3.3.1-branch/Source/WebKit/ChangeLog</a></li>
<li><a href="#branchessafari612331branchSourceWebKitPlatformIPCConnectioncpp">branches/safari-612.3.3.1-branch/Source/WebKit/Platform/IPC/Connection.cpp</a></li>
<li><a href="#branchessafari612331branchSourceWebKitScriptswebkitmodelpy">branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/model.py</a></li>
<li><a href="#branchessafari612331branchSourceWebKitScriptswebkittestsMessageNamescpp">branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp</a></li>
<li><a href="#branchessafari612331branchSourceWebKitScriptswebkittestsMessageNamesh">branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.h</a></li>
<li><a href="#branchessafari612331branchSourceWebKitUIProcessNetworkNetworkProcessProxycpp">branches/safari-612.3.3.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari612331branchSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-612.3.3.1-branch/Source/WebKit/ChangeLog (285226 => 285227)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-612.3.3.1-branch/Source/WebKit/ChangeLog 2021-11-03 20:26:00 UTC (rev 285226)
+++ branches/safari-612.3.3.1-branch/Source/WebKit/ChangeLog    2021-11-03 20:26:04 UTC (rev 285227)
</span><span class="lines">@@ -1,5 +1,66 @@
</span><span class="cx"> 2021-11-03  Russell Epstein  <repstein@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r285177. rdar://problem/84987165
+
+    Terminate unresponsive network process by crashing it
+    https://bugs.webkit.org/show_bug.cgi?id=232603
+    
+    Reviewed by Chris Dumez.
+    
+    UI process currently kills network process when it does not respond message in some time (network process being
+    unresponsive). We've found one common case where network process becomes unresponsive is that it is blocked by
+    some slow operation on the main thread (like file operation in rdar://84511633). To understand what the
+    operations are and make a fix, we now ask network process to crash itself on IPC thread. In this way, we can get
+    crash report that includes the call stack of the main thread. To avoid generating too many crash reports, we
+    only send the crash message to network process when it becomes unresponsive multiple times in a short time
+    period.
+    
+    * Platform/IPC/Connection.cpp:
+    (IPC::terminateDueToIPCTerminateMessage):
+    (IPC::Connection::processIncomingMessage):
+    * Scripts/webkit/model.py:
+    * Scripts/webkit/tests/MessageNames.cpp:
+    (IPC::description):
+    (IPC::receiverName):
+    (IPC::isValidMessageName):
+    * Scripts/webkit/tests/MessageNames.h:
+    * UIProcess/Network/NetworkProcessProxy.cpp:
+    (WebKit::shouldTerminateNetworkProcessBySendingMessage):
+    (WebKit::NetworkProcessProxy::didBecomeUnresponsive):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@285177 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-11-02  Sihui Liu  <sihui_liu@apple.com>
+
+            Terminate unresponsive network process by crashing it
+            https://bugs.webkit.org/show_bug.cgi?id=232603
+
+            Reviewed by Chris Dumez.
+
+            UI process currently kills network process when it does not respond message in some time (network process being
+            unresponsive). We've found one common case where network process becomes unresponsive is that it is blocked by
+            some slow operation on the main thread (like file operation in rdar://84511633). To understand what the
+            operations are and make a fix, we now ask network process to crash itself on IPC thread. In this way, we can get
+            crash report that includes the call stack of the main thread. To avoid generating too many crash reports, we
+            only send the crash message to network process when it becomes unresponsive multiple times in a short time
+            period.
+
+            * Platform/IPC/Connection.cpp:
+            (IPC::terminateDueToIPCTerminateMessage):
+            (IPC::Connection::processIncomingMessage):
+            * Scripts/webkit/model.py:
+            * Scripts/webkit/tests/MessageNames.cpp:
+            (IPC::description):
+            (IPC::receiverName):
+            (IPC::isValidMessageName):
+            * Scripts/webkit/tests/MessageNames.h:
+            * UIProcess/Network/NetworkProcessProxy.cpp:
+            (WebKit::shouldTerminateNetworkProcessBySendingMessage):
+            (WebKit::NetworkProcessProxy::didBecomeUnresponsive):
+
+2021-11-03  Russell Epstein  <repstein@apple.com>
+
</ins><span class="cx">         Cherry-pick r285115. rdar://problem/84984094
</span><span class="cx"> 
</span><span class="cx">     Increase responsiveness timeout for network process
</span></span></pre></div>
<a id="branchessafari612331branchSourceWebKitPlatformIPCConnectioncpp"></a>
<div class="modfile"><h4>Modified: branches/safari-612.3.3.1-branch/Source/WebKit/Platform/IPC/Connection.cpp (285226 => 285227)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-612.3.3.1-branch/Source/WebKit/Platform/IPC/Connection.cpp       2021-11-03 20:26:00 UTC (rev 285226)
+++ branches/safari-612.3.3.1-branch/Source/WebKit/Platform/IPC/Connection.cpp  2021-11-03 20:26:04 UTC (rev 285227)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> #include "MachMessage.h"
</span><ins>+#include "WKCrashReporter.h"
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if USE(UNIX_DOMAIN_SOCKETS)
</span><span class="lines">@@ -744,6 +745,16 @@
</span><span class="cx">     // This can happen if the send timed out, so it's fine to ignore.
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static NEVER_INLINE NO_RETURN_DUE_TO_CRASH void terminateDueToIPCTerminateMessage()
+{
+#if PLATFORM(COCOA)
+    WebKit::logAndSetCrashLogMessage("Receives Terminate message");
+#else
+    WTFLogAlways("Receives Terminate message");
+#endif
+    CRASH();
+}
+
</ins><span class="cx"> void Connection::processIncomingMessage(std::unique_ptr<Decoder> message)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(message->messageReceiverName() != ReceiverName::Invalid);
</span><span class="lines">@@ -753,6 +764,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (message->messageName() == MessageName::Terminate)
+        return terminateDueToIPCTerminateMessage();
+
</ins><span class="cx">     if (!MessageReceiveQueueMap::isValidMessage(*message)) {
</span><span class="cx">         RunLoop::main().dispatch([protectedThis = makeRef(*this), messageName = message->messageName()]() mutable {
</span><span class="cx">             protectedThis->dispatchDidReceiveInvalidMessage(messageName);
</span></span></pre></div>
<a id="branchessafari612331branchSourceWebKitScriptswebkitmodelpy"></a>
<div class="modfile"><h4>Modified: branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/model.py (285226 => 285227)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/model.py   2021-11-03 20:26:00 UTC (rev 285226)
+++ branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/model.py      2021-11-03 20:26:04 UTC (rev 285227)
</span><span class="lines">@@ -77,7 +77,8 @@
</span><span class="cx">     Message('InitializeConnection', [], [], attributes=[BUILTIN_ATTRIBUTE], condition="PLATFORM(COCOA)"),
</span><span class="cx">     Message('LegacySessionState', [], [], attributes=[BUILTIN_ATTRIBUTE], condition=None),
</span><span class="cx">     Message('SetStreamDestinationID', [], [], attributes=[BUILTIN_ATTRIBUTE], condition=None),
</span><del>-    Message('ProcessOutOfStreamMessage', [], [], attributes=[BUILTIN_ATTRIBUTE], condition=None)
</del><ins>+    Message('ProcessOutOfStreamMessage', [], [], attributes=[BUILTIN_ATTRIBUTE], condition=None),
+    Message('Terminate', [], [], attributes=[BUILTIN_ATTRIBUTE], condition=None),
</ins><span class="cx"> ], condition=None)
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari612331branchSourceWebKitScriptswebkittestsMessageNamescpp"></a>
<div class="modfile"><h4>Modified: branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp (285226 => 285227)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp     2021-11-03 20:26:00 UTC (rev 285226)
+++ branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp        2021-11-03 20:26:04 UTC (rev 285227)
</span><span class="lines">@@ -156,6 +156,8 @@
</span><span class="cx">         return "SetStreamDestinationID";
</span><span class="cx">     case MessageName::SyncMessageReply:
</span><span class="cx">         return "SyncMessageReply";
</span><ins>+    case MessageName::Terminate:
+        return "Terminate";
</ins><span class="cx">     case MessageName::TestWithSuperclass_TestAsyncMessageReply:
</span><span class="cx">         return "TestWithSuperclass_TestAsyncMessageReply";
</span><span class="cx">     case MessageName::TestWithSuperclass_TestAsyncMessageWithConnectionReply:
</span><span class="lines">@@ -258,6 +260,7 @@
</span><span class="cx">     case MessageName::ProcessOutOfStreamMessage:
</span><span class="cx">     case MessageName::SetStreamDestinationID:
</span><span class="cx">     case MessageName::SyncMessageReply:
</span><ins>+    case MessageName::Terminate:
</ins><span class="cx">         return ReceiverName::IPC;
</span><span class="cx">     case MessageName::TestWithSuperclass_TestAsyncMessageReply:
</span><span class="cx">     case MessageName::TestWithSuperclass_TestAsyncMessageWithConnectionReply:
</span><span class="lines">@@ -466,6 +469,8 @@
</span><span class="cx">         return true;
</span><span class="cx">     if (messageName == IPC::MessageName::SyncMessageReply)
</span><span class="cx">         return true;
</span><ins>+    if (messageName == IPC::MessageName::Terminate)
+        return true;
</ins><span class="cx"> #if ENABLE(TEST_FEATURE)
</span><span class="cx">     if (messageName == IPC::MessageName::TestWithSuperclass_TestAsyncMessageReply)
</span><span class="cx">         return true;
</span></span></pre></div>
<a id="branchessafari612331branchSourceWebKitScriptswebkittestsMessageNamesh"></a>
<div class="modfile"><h4>Modified: branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.h (285226 => 285227)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.h       2021-11-03 20:26:00 UTC (rev 285226)
+++ branches/safari-612.3.3.1-branch/Source/WebKit/Scripts/webkit/tests/MessageNames.h  2021-11-03 20:26:04 UTC (rev 285227)
</span><span class="lines">@@ -107,6 +107,7 @@
</span><span class="cx">     , ProcessOutOfStreamMessage
</span><span class="cx">     , SetStreamDestinationID
</span><span class="cx">     , SyncMessageReply
</span><ins>+    , Terminate
</ins><span class="cx">     , TestWithSuperclass_TestAsyncMessageReply
</span><span class="cx">     , TestWithSuperclass_TestAsyncMessageWithConnectionReply
</span><span class="cx">     , TestWithSuperclass_TestAsyncMessageWithMultipleArgumentsReply
</span></span></pre></div>
<a id="branchessafari612331branchSourceWebKitUIProcessNetworkNetworkProcessProxycpp"></a>
<div class="modfile"><h4>Modified: branches/safari-612.3.3.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (285226 => 285227)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-612.3.3.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2021-11-03 20:26:00 UTC (rev 285226)
+++ branches/safari-612.3.3.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp    2021-11-03 20:26:04 UTC (rev 285227)
</span><span class="lines">@@ -86,6 +86,8 @@
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="cx"> static constexpr Seconds networkProcessResponsivenessTimeout = 6_s;
</span><ins>+static constexpr int unresponsivenessCountLimit = 3;
+static constexpr Seconds unresponsivenessCheckPeriod = 15_s;
</ins><span class="cx"> 
</span><span class="cx"> static HashSet<NetworkProcessProxy*>& networkProcessesSet()
</span><span class="cx"> {
</span><span class="lines">@@ -94,6 +96,25 @@
</span><span class="cx">     return set;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool shouldTerminateNetworkProcessBySendingMessage()
+{
+    static WallTime unresponsivenessPeriodStartTime = WallTime::now();
+    static int unresponsivenessCountDuringThisPeriod = 0;
+    auto now = WallTime::now();
+
+    if (now - unresponsivenessPeriodStartTime > unresponsivenessCheckPeriod) {
+        unresponsivenessCountDuringThisPeriod = 1;
+        unresponsivenessPeriodStartTime = now;
+        return false;
+    }
+
+    ++unresponsivenessCountDuringThisPeriod;
+    if (unresponsivenessCountDuringThisPeriod >= unresponsivenessCountLimit)
+        return true;
+
+    return false;
+}
+
</ins><span class="cx"> Vector<Ref<NetworkProcessProxy>> NetworkProcessProxy::allNetworkProcesses()
</span><span class="cx"> {
</span><span class="cx">     Vector<Ref<NetworkProcessProxy>> processes;
</span><span class="lines">@@ -127,6 +148,19 @@
</span><span class="cx"> void NetworkProcessProxy::didBecomeUnresponsive()
</span><span class="cx"> {
</span><span class="cx">     RELEASE_LOG_ERROR(Process, "NetworkProcessProxy::didBecomeUnresponsive: NetworkProcess with PID %d became unresponsive, terminating it", processIdentifier());
</span><ins>+
+    // Let network process terminates itself and generate crash report for investigation of hangs.
+    // We currently only do this when network process becomes unresponsive multiple times in a short
+    // time period to avoid generating too many crash reports with same back trace on user's device.
+    if (shouldTerminateNetworkProcessBySendingMessage()) {
+        sendMessage(makeUniqueRef<IPC::Encoder>(IPC::MessageName::Terminate, 0), { });
+        RunLoop::main().dispatchAfter(1_s, [weakThis = WeakPtr { *this }] () mutable {
+            if (weakThis)
+                weakThis->terminate();
+        });
+        return;
+    }
+
</ins><span class="cx">     terminate();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>