Skip to content

Commit 064760c

Browse files
WebContent processes crash when the network process crashes with pending connection requests
https://bugs.webkit.org/show_bug.cgi?id=174065 <rdar://problem/30359835> Reviewed by Tim Horton. Source/WebKit2: The bug was caused by the UI process clearing away pending network connection requests whenever the existing network process crashed. This resulted in WebContent process killing itself inside ensureNetworkProcessConnection. Fixed the bug by re-launching a new network process when this happens. We don't try to re-launch a new process if the previous attempt to launch a network process had failed. This patch splits NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch into networkProcessFailedToLaunch and networkProcessCrashed to differentiate those two cases, and invoke the respective callbacks in WebProcessPool. * UIProcess/API/Cocoa/WKProcessPool.mm: (-[WKProcessPool _networkProcessIdentifier]): Added. * UIProcess/API/Cocoa/WKProcessPoolPrivate.h: * UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::networkProcessCrashed): Added. (WebKit::NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch): Split into the two following functions. (WebKit::NetworkProcessProxy::networkProcessFailedToLaunch): Extracted from networkProcessCrashedOrFailedToLaunch. (WebKit::NetworkProcessProxy::clearCallbackStates): Extracted from networkProcessCrashedOrFailedToLaunch (WebKit::NetworkProcessProxy::didClose): Call networkProcessCrashed. (WebKit::NetworkProcessProxy::didFinishLaunching): Call networkProcessFailedToLaunch. * UIProcess/Network/NetworkProcessProxy.h: * UIProcess/WebProcessPool.cpp: (WebKit::WebProcessPool::networkProcessCrashed): Start a new network process when there are pending connection requests the crached network failed to fullfil. (WebKit::WebProcessPool::networkProcessFailedToLaunch): * UIProcess/WebProcessPool.h: Tools: Add a API to ensure UI process tries to relaunch a new network process when the network process crashes with pending network connection requests. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKit2/NetworkProcessCrashWithPendingConnection.mm: Added. * TestWebKitAPI/cocoa/TestNavigationDelegate.h: * TestWebKitAPI/cocoa/TestNavigationDelegate.mm: (-[TestNavigationDelegate webViewWebContentProcessDidTerminate:]): Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@219087 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 431c5c6 commit 064760c

12 files changed

+223
-11
lines changed

Source/WebKit2/ChangeLog

+34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1+
2017-07-03 Ryosuke Niwa <[email protected]>
2+
3+
WebContent processes crash when the network process crashes with pending connection requests
4+
https://bugs.webkit.org/show_bug.cgi?id=174065
5+
<rdar://problem/30359835>
6+
7+
Reviewed by Tim Horton.
8+
9+
The bug was caused by the UI process clearing away pending network connection requests whenever the existing
10+
network process crashed. This resulted in WebContent process killing itself inside ensureNetworkProcessConnection.
11+
12+
Fixed the bug by re-launching a new network process when this happens. We don't try to re-launch a new process
13+
if the previous attempt to launch a network process had failed.
14+
15+
This patch splits NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch into networkProcessFailedToLaunch
16+
and networkProcessCrashed to differentiate those two cases, and invoke the respective callbacks in WebProcessPool.
17+
18+
* UIProcess/API/Cocoa/WKProcessPool.mm:
19+
(-[WKProcessPool _networkProcessIdentifier]): Added.
20+
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
21+
* UIProcess/Network/NetworkProcessProxy.cpp:
22+
(WebKit::NetworkProcessProxy::networkProcessCrashed): Added.
23+
(WebKit::NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch): Split into the two following functions.
24+
(WebKit::NetworkProcessProxy::networkProcessFailedToLaunch): Extracted from networkProcessCrashedOrFailedToLaunch.
25+
(WebKit::NetworkProcessProxy::clearCallbackStates): Extracted from networkProcessCrashedOrFailedToLaunch
26+
(WebKit::NetworkProcessProxy::didClose): Call networkProcessCrashed.
27+
(WebKit::NetworkProcessProxy::didFinishLaunching): Call networkProcessFailedToLaunch.
28+
* UIProcess/Network/NetworkProcessProxy.h:
29+
* UIProcess/WebProcessPool.cpp:
30+
(WebKit::WebProcessPool::networkProcessCrashed): Start a new network process when there are pending connection
31+
requests the crached network failed to fullfil.
32+
(WebKit::WebProcessPool::networkProcessFailedToLaunch):
33+
* UIProcess/WebProcessPool.h:
34+
135
2017-07-03 Eric Carlson <[email protected]>
236

337
[MediaStream] Protect request and web view during gUM client callback

Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm

+5
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ - (void)_terminateNetworkProcess
394394
_processPool->terminateNetworkProcess();
395395
}
396396

397+
- (pid_t)_networkProcessIdentifier
398+
{
399+
return _processPool->networkProcessIdentifier();
400+
}
401+
397402
- (void)_syncNetworkProcessCookies
398403
{
399404
_processPool->syncNetworkProcessCookies();

Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
- (void)_terminateDatabaseProcess;
7676
- (void)_terminateNetworkProcess;
7777

78+
// Test only.
79+
- (pid_t)_networkProcessIdentifier WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
80+
7881
// Test only.
7982
- (size_t)_webProcessCount WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
8083
- (void)_syncNetworkProcessCookies WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));

Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp

+22-6
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,20 @@ void NetworkProcessProxy::deleteWebsiteDataForOrigins(SessionID sessionID, Optio
164164
send(Messages::NetworkProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins, cookieHostNames, callbackID), 0);
165165
}
166166

167-
void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch()
167+
void NetworkProcessProxy::networkProcessCrashed()
168+
{
169+
clearCallbackStates();
170+
171+
Vector<Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>> pendingReplies;
172+
pendingReplies.reserveInitialCapacity(m_pendingConnectionReplies.size());
173+
for (auto& reply : m_pendingConnectionReplies)
174+
pendingReplies.append(WTFMove(reply));
175+
176+
// Tell the network process manager to forget about this network process proxy. This may cause us to be deleted.
177+
m_processPool.networkProcessCrashed(*this, WTFMove(pendingReplies));
178+
}
179+
180+
void NetworkProcessProxy::networkProcessFailedToLaunch()
168181
{
169182
// The network process must have crashed or exited, send any pending sync replies we might have.
170183
while (!m_pendingConnectionReplies.isEmpty()) {
@@ -178,7 +191,13 @@ void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch()
178191
notImplemented();
179192
#endif
180193
}
194+
clearCallbackStates();
195+
// Tell the network process manager to forget about this network process proxy. This may cause us to be deleted.
196+
m_processPool.networkProcessFailedToLaunch(*this);
197+
}
181198

199+
void NetworkProcessProxy::clearCallbackStates()
200+
{
182201
for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values())
183202
callback(WebsiteData());
184203
m_pendingFetchWebsiteDataCallbacks.clear();
@@ -190,9 +209,6 @@ void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch()
190209
for (const auto& callback : m_pendingDeleteWebsiteDataForOriginsCallbacks.values())
191210
callback();
192211
m_pendingDeleteWebsiteDataForOriginsCallbacks.clear();
193-
194-
// Tell the network process manager to forget about this network process proxy. This may cause us to be deleted.
195-
m_processPool.networkProcessCrashed(this);
196212
}
197213

198214
void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
@@ -223,7 +239,7 @@ void NetworkProcessProxy::didClose(IPC::Connection&)
223239
m_tokenForHoldingLockedFiles = nullptr;
224240

225241
// This may cause us to be deleted.
226-
networkProcessCrashedOrFailedToLaunch();
242+
networkProcessCrashed();
227243
}
228244

229245
void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
@@ -302,7 +318,7 @@ void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Con
302318
ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier);
303319

304320
if (IPC::Connection::identifierIsNull(connectionIdentifier)) {
305-
networkProcessCrashedOrFailedToLaunch();
321+
networkProcessFailedToLaunch();
306322
return;
307323
}
308324

Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ class NetworkProcessProxy : public ChildProcessProxy, private ProcessThrottlerCl
8686
void connectionWillOpen(IPC::Connection&) override;
8787
void processWillShutDown(IPC::Connection&) override;
8888

89-
void networkProcessCrashedOrFailedToLaunch();
89+
void networkProcessFailedToLaunch();
90+
void networkProcessCrashed();
91+
void clearCallbackStates();
9092

9193
// ProcessThrottlerClient
9294
void sendProcessWillSuspendImminently() override;

Source/WebKit2/UIProcess/WebProcessPool.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -490,14 +490,25 @@ NetworkProcessProxy& WebProcessPool::ensureNetworkProcess(WebsiteDataStore* with
490490
return *m_networkProcess;
491491
}
492492

493-
void WebProcessPool::networkProcessCrashed(NetworkProcessProxy* networkProcessProxy)
493+
void WebProcessPool::networkProcessCrashed(NetworkProcessProxy& networkProcessProxy, Vector<Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>>&& pendingReplies)
494+
{
495+
networkProcessFailedToLaunch(networkProcessProxy);
496+
ASSERT(!m_networkProcess);
497+
if (pendingReplies.isEmpty())
498+
return;
499+
auto& newNetworkProcess = ensureNetworkProcess();
500+
for (auto& reply : pendingReplies)
501+
newNetworkProcess.getNetworkProcessConnection(WTFMove(reply));
502+
}
503+
504+
void WebProcessPool::networkProcessFailedToLaunch(NetworkProcessProxy& networkProcessProxy)
494505
{
495506
ASSERT(m_networkProcess);
496-
ASSERT(networkProcessProxy == m_networkProcess.get());
507+
ASSERT(&networkProcessProxy == m_networkProcess.get());
497508
m_didNetworkProcessCrash = true;
498509

499510
for (auto& supplement : m_supplements.values())
500-
supplement->processDidClose(networkProcessProxy);
511+
supplement->processDidClose(&networkProcessProxy);
501512

502513
m_client.networkProcessDidCrash(this);
503514

Source/WebKit2/UIProcess/WebProcessPool.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPo
315315
// Network Process Management
316316
NetworkProcessProxy& ensureNetworkProcess(WebsiteDataStore* withWebsiteDataStore = nullptr);
317317
NetworkProcessProxy* networkProcess() { return m_networkProcess.get(); }
318-
void networkProcessCrashed(NetworkProcessProxy*);
318+
void networkProcessCrashed(NetworkProcessProxy&, Vector<Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>>&&);
319+
void networkProcessFailedToLaunch(NetworkProcessProxy&);
319320

320321
void getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&&);
321322

Tools/ChangeLog

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
2017-07-03 Ryosuke Niwa <[email protected]>
2+
3+
WebContent processes crash when the network process crashes with pending connection requests
4+
https://bugs.webkit.org/show_bug.cgi?id=174065
5+
<rdar://problem/30359835>
6+
7+
Reviewed by Tim Horton.
8+
9+
Add a API to ensure UI process tries to relaunch a new network process when the network process
10+
crashes with pending network connection requests.
11+
12+
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
13+
* TestWebKitAPI/Tests/WebKit2/NetworkProcessCrashWithPendingConnection.mm: Added.
14+
* TestWebKitAPI/cocoa/TestNavigationDelegate.h:
15+
* TestWebKitAPI/cocoa/TestNavigationDelegate.mm:
16+
(-[TestNavigationDelegate webViewWebContentProcessDidTerminate:]): Added.
17+
118
2017-07-03 Eric Carlson <[email protected]>
219

320
[MediaStream] Protect request and web view during gUM client callback

Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@
513513
9984FACC1CFFAF60008D198C /* WKWebViewTextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */; };
514514
9984FACE1CFFB090008D198C /* editable-body.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9984FACD1CFFB038008D198C /* editable-body.html */; };
515515
9B0786A51C5885C300D159E3 /* InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B0786A41C5885C300D159E3 /* InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp */; };
516+
9B19CDA01F06DFE3000548DD /* NetworkProcessCrashWithPendingConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B19CD9E1F06DFE3000548DD /* NetworkProcessCrashWithPendingConnection.mm */; };
516517
9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; };
517518
9B270FEE1DDC2C0B002D53F3 /* closed-shadow-tree-test.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B270FED1DDC25FD002D53F3 /* closed-shadow-tree-test.html */; };
518519
9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
@@ -1390,6 +1391,7 @@
13901391
9984FACD1CFFB038008D198C /* editable-body.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "editable-body.html"; sourceTree = "<group>"; };
13911392
9B0786A21C58830F00D159E3 /* InjectedBundleMakeAllShadowRootsOpen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleMakeAllShadowRootsOpen.cpp; sourceTree = "<group>"; };
13921393
9B0786A41C5885C300D159E3 /* InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp; sourceTree = "<group>"; };
1394+
9B19CD9E1F06DFE3000548DD /* NetworkProcessCrashWithPendingConnection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkProcessCrashWithPendingConnection.mm; path = WebKit2/NetworkProcessCrashWithPendingConnection.mm; sourceTree = "<group>"; };
13931395
9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLFormCollectionNamedItem.mm; sourceTree = "<group>"; };
13941396
9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLFormCollectionNamedItem.html; sourceTree = "<group>"; };
13951397
9B270FED1DDC25FD002D53F3 /* closed-shadow-tree-test.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "closed-shadow-tree-test.html"; sourceTree = "<group>"; };
@@ -2164,6 +2166,7 @@
21642166
2D1646E11D1862CD00015A1A /* DeferredViewInWindowStateChange.mm */,
21652167
B55AD1D1179F336600AC1494 /* PreventImageLoadWithAutoResizing.mm */,
21662168
B55AD1D3179F3ABF00AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp */,
2169+
9B19CD9E1F06DFE3000548DD /* NetworkProcessCrashWithPendingConnection.mm */,
21672170
2943BE84161DFEB800999E3D /* UserContentTest.mm */,
21682171
BC3C4C7D14587AA60025FB62 /* WKBrowsingContextGroupTest.mm */,
21692172
BC3C4C7014575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm */,
@@ -3126,6 +3129,7 @@
31263129
7CCE7F051A411AE600447C4C /* NewFirstVisuallyNonEmptyLayoutFrames.cpp in Sources */,
31273130
2ECFF5551D9B12F800B55394 /* NowPlayingControlsTests.mm in Sources */,
31283131
A10F047E1E3AD29C00C95E19 /* NSFileManagerExtras.mm in Sources */,
3132+
9B19CDA01F06DFE3000548DD /* NetworkProcessCrashWithPendingConnection.mm in Sources */,
31293133
37A22AA71DCAA27200AFBFC4 /* ObservedRenderingProgressEventsAfterCrash.mm in Sources */,
31303134
7CCE7F251A411AF600447C4C /* OpenAndCloseWindow.mm in Sources */,
31313135
CEBCA12F1E3A660100C73293 /* OverrideContentSecurityPolicy.mm in Sources */,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright (C) 2017 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#import "config.h"
27+
28+
#import "PlatformUtilities.h"
29+
#import "Test.h"
30+
#import "TestNavigationDelegate.h"
31+
#import <WebKit/WKContextPrivate.h>
32+
#import <WebKit/WKProcessGroupPrivate.h>
33+
#import <WebKit/WKProcessPoolPrivate.h>
34+
#import <WebKit/WKWebViewPrivate.h>
35+
#import <WebKit/WebKit.h>
36+
#import <wtf/RetainPtr.h>
37+
38+
#if WK_API_ENABLED
39+
40+
namespace TestWebKitAPI {
41+
42+
static bool loadedOrCrashed = false;
43+
static bool loaded = false;
44+
static bool webProcessCrashed = false;
45+
static bool networkProcessCrashed = false;
46+
47+
TEST(WebKit2, NetworkProcessCrashWithPendingConnection)
48+
{
49+
RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
50+
RetainPtr<WKProcessPool> processPool = adoptNS([[WKProcessPool alloc] init]);
51+
[configuration setProcessPool:processPool.get()];
52+
53+
// FIXME: Adopt the new API once it's added in webkit.org/b/174061.
54+
WKContextClientV0 client;
55+
memset(&client, 0, sizeof(client));
56+
client.networkProcessDidCrash = [](WKContextRef context, const void* clientInfo) {
57+
networkProcessCrashed = true;
58+
};
59+
WKContextSetClient(static_cast<WKContextRef>(processPool.get()), &client.base);
60+
61+
RetainPtr<WKWebView> webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
62+
RetainPtr<WKWebView> webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
63+
64+
[webView1.get() loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
65+
[webView1.get() _test_waitForDidFinishNavigation];
66+
67+
[webView2.get() loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
68+
[webView2.get() _test_waitForDidFinishNavigation];
69+
70+
pid_t webView1PID = [webView1.get() _webProcessIdentifier];
71+
pid_t webView2PID = [webView2.get() _webProcessIdentifier];
72+
EXPECT_NE(webView1PID, webView2PID);
73+
74+
pid_t initialNetworkProcessIdentififer = [processPool.get() _networkProcessIdentifier];
75+
EXPECT_NE(initialNetworkProcessIdentififer, 0);
76+
kill(initialNetworkProcessIdentififer, SIGKILL);
77+
Util::run(&networkProcessCrashed);
78+
networkProcessCrashed = false;
79+
80+
[webView1.get() loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
81+
[webView1.get() _test_waitForDidFinishNavigation];
82+
83+
pid_t relaunchedNetworkProcessIdentifier = [processPool.get() _networkProcessIdentifier];
84+
EXPECT_NE(initialNetworkProcessIdentififer, relaunchedNetworkProcessIdentifier);
85+
EXPECT_FALSE(networkProcessCrashed);
86+
87+
kill(relaunchedNetworkProcessIdentifier, SIGSTOP);
88+
89+
[webView2.get() loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
90+
Util::sleep(0.5); // Wait for the WebContent process to send CreateNetworkConnectionToWebProcess
91+
kill(relaunchedNetworkProcessIdentifier, SIGKILL);
92+
Util::run(&networkProcessCrashed);
93+
94+
auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
95+
loadedOrCrashed = false;
96+
[navigationDelegate setDidFinishNavigation:^(WKWebView *, WKNavigation *) {
97+
loadedOrCrashed = true;
98+
loaded = true;
99+
}];
100+
[navigationDelegate setWebContentProcessDidTerminate:^(WKWebView *) {
101+
loadedOrCrashed = true;
102+
webProcessCrashed = true;
103+
}];
104+
[webView2 setNavigationDelegate:navigationDelegate.get()];
105+
TestWebKitAPI::Util::run(&loadedOrCrashed);
106+
EXPECT_TRUE(loaded);
107+
EXPECT_FALSE(webProcessCrashed);
108+
}
109+
110+
} // namespace TestWebKitAPI
111+
112+
#endif

Tools/TestWebKitAPI/cocoa/TestNavigationDelegate.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
@property (nonatomic, copy) void (^didFailProvisionalNavigation)(WKWebView *, WKNavigation *, NSError *);
3636
@property (nonatomic, copy) void (^didFinishNavigation)(WKWebView *, WKNavigation *);
3737
@property (nonatomic, copy) void (^renderingProgressDidChange)(WKWebView *, _WKRenderingProgressEvents);
38+
@property (nonatomic, copy) void (^webContentProcessDidTerminate)(WKWebView *);
3839

3940
- (void)waitForDidFinishNavigation;
4041

Tools/TestWebKitAPI/cocoa/TestNavigationDelegate.mm

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigat
4545
_didFinishNavigation(webView, navigation);
4646
}
4747

48+
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
49+
{
50+
if (_webContentProcessDidTerminate)
51+
_webContentProcessDidTerminate(webView);
52+
}
53+
4854
- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
4955
{
5056
if (_renderingProgressDidChange)

0 commit comments

Comments
 (0)