Title: [232948] trunk
Revision
232948
Author
[email protected]
Date
2018-06-18 14:46:58 -0700 (Mon, 18 Jun 2018)

Log Message

Crash under WebProcessPool::networkProcessFailedToLaunch():
https://bugs.webkit.org/show_bug.cgi?id=186784
<rdar://problem/33535377>

Reviewed by Brady Eidson.

Source/WebKit:

* UIProcess/API/Cocoa/WKProcessPool.mm:
(+[WKProcessPool _allProcessPoolsForTesting]):
Add SPI to retrieve all WebProcessPool for testing purposes.

* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::clearCallbackStates):
Make iteration over completion handlers robust against completion handlers
getting removed while we iterate.

(WebKit::NetworkProcessProxy::didClose):
Ref the WebProcessPool (which keeps the NetworkProcessProxy alive too)
as several calls within this method might cause the WebProcessPool /
NetworkProcessProxy to get destroyed.

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (232947 => 232948)


--- trunk/Source/WebKit/ChangeLog	2018-06-18 21:45:23 UTC (rev 232947)
+++ trunk/Source/WebKit/ChangeLog	2018-06-18 21:46:58 UTC (rev 232948)
@@ -1,5 +1,28 @@
 2018-06-18  Chris Dumez  <[email protected]>
 
+        Crash under WebProcessPool::networkProcessFailedToLaunch():
+        https://bugs.webkit.org/show_bug.cgi?id=186784
+        <rdar://problem/33535377>
+
+        Reviewed by Brady Eidson.
+
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (+[WKProcessPool _allProcessPoolsForTesting]):
+        Add SPI to retrieve all WebProcessPool for testing purposes.
+
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::clearCallbackStates):
+        Make iteration over completion handlers robust against completion handlers
+        getting removed while we iterate.
+
+        (WebKit::NetworkProcessProxy::didClose):
+        Ref the WebProcessPool (which keeps the NetworkProcessProxy alive too)
+        as several calls within this method might cause the WebProcessPool /
+        NetworkProcessProxy to get destroyed.
+
+2018-06-18  Chris Dumez  <[email protected]>
+
         Implement IPC throttling to keep the main thread responsive when a process misbehaves
         https://bugs.webkit.org/show_bug.cgi?id=186607
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm (232947 => 232948)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2018-06-18 21:45:23 UTC (rev 232947)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2018-06-18 21:46:58 UTC (rev 232948)
@@ -161,6 +161,15 @@
     return sharedProcessPool;
 }
 
++ (NSArray<WKProcessPool *> *)_allProcessPoolsForTesting
+{
+    auto& allPools = WebKit::WebProcessPool::allProcessPools();
+    auto nsAllPools = adoptNS([[NSMutableArray alloc] initWithCapacity:allPools.size()]);
+    for (auto* pool : allPools)
+        [nsAllPools addObject:wrapper(*pool)];
+    return nsAllPools.autorelease();
+}
+
 + (NSURL *)_websiteDataURLForContainerWithURL:(NSURL *)containerURL
 {
     return [WKProcessPool _websiteDataURLForContainerWithURL:containerURL bundleIdentifierIfNotInContainer:nil];

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (232947 => 232948)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2018-06-18 21:45:23 UTC (rev 232947)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2018-06-18 21:46:58 UTC (rev 232948)
@@ -42,6 +42,8 @@
 
 + (WKProcessPool *)_sharedProcessPool;
 
++ (NSArray<WKProcessPool *> *)_allProcessPoolsForTesting WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @property (nonatomic, readonly) _WKProcessPoolConfiguration *_configuration;
 
 - (void)_setAllowsSpecificHTTPSCertificate:(NSArray *)certificateChain forHost:(NSString *)host;

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (232947 => 232948)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2018-06-18 21:45:23 UTC (rev 232947)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2018-06-18 21:46:58 UTC (rev 232948)
@@ -223,17 +223,14 @@
 
 void NetworkProcessProxy::clearCallbackStates()
 {
-    for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values())
-        callback(WebsiteData());
-    m_pendingFetchWebsiteDataCallbacks.clear();
+    while (!m_pendingFetchWebsiteDataCallbacks.isEmpty())
+        m_pendingFetchWebsiteDataCallbacks.take(m_pendingFetchWebsiteDataCallbacks.begin()->key)(WebsiteData { });
 
-    for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values())
-        callback();
-    m_pendingDeleteWebsiteDataCallbacks.clear();
+    while (!m_pendingDeleteWebsiteDataCallbacks.isEmpty())
+        m_pendingDeleteWebsiteDataCallbacks.take(m_pendingDeleteWebsiteDataCallbacks.begin()->key)();
 
-    for (const auto& callback : m_pendingDeleteWebsiteDataForOriginsCallbacks.values())
-        callback();
-    m_pendingDeleteWebsiteDataForOriginsCallbacks.clear();
+    while (!m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty())
+        m_pendingDeleteWebsiteDataForOriginsCallbacks.take(m_pendingDeleteWebsiteDataForOriginsCallbacks.begin()->key)();
 }
 
 void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
@@ -257,6 +254,8 @@
 
 void NetworkProcessProxy::didClose(IPC::Connection&)
 {
+    auto protectedProcessPool = makeRef(m_processPool);
+
     if (m_downloadProxyMap)
         m_downloadProxyMap->processDidClose();
 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)

Modified: trunk/Tools/ChangeLog (232947 => 232948)


--- trunk/Tools/ChangeLog	2018-06-18 21:45:23 UTC (rev 232947)
+++ trunk/Tools/ChangeLog	2018-06-18 21:46:58 UTC (rev 232948)
@@ -1,3 +1,16 @@
+2018-06-18  Chris Dumez  <[email protected]>
+
+        Crash under WebProcessPool::networkProcessFailedToLaunch():
+        https://bugs.webkit.org/show_bug.cgi?id=186784
+        <rdar://problem/33535377>
+
+        Reviewed by Brady Eidson.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:
+        (TEST):
+
 2018-06-18  Zan Dobersek  <[email protected]>
 
         [webkitpy] WPTRunner should remove any metadata content before (re)generating it

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm (232947 => 232948)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm	2018-06-18 21:45:23 UTC (rev 232947)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm	2018-06-18 21:46:58 UTC (rev 232948)
@@ -285,6 +285,60 @@
     TestWebKitAPI::Util::run(&readyToContinue);
 }
 
+TEST(WebKit, CustomDataStoreDestroyWhileFetchingNetworkProcessData)
+{
+    NSURL *cookieStorageFile = [NSURL fileURLWithPath:[@"~/Library/WebKit/TestWebKitAPI/CustomWebsiteData/CookieStorage/Cookie.File" stringByExpandingTildeInPath] isDirectory:NO];
+    [[NSFileManager defaultManager] removeItemAtURL:cookieStorageFile error:nil];
+
+    auto websiteDataTypes = adoptNS([[NSSet alloc] initWithArray:@[WKWebsiteDataTypeCookies]]);
+    static bool readyToContinue;
+
+    auto websiteDataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]);
+    websiteDataStoreConfiguration.get()._cookieStorageFile = cookieStorageFile;
+
+    @autoreleasepool {
+        auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:websiteDataStoreConfiguration.get()]);
+
+        // Fetch records
+        [dataStore fetchDataRecordsOfTypes:websiteDataTypes.get() completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+            EXPECT_EQ((int)dataRecords.count, 0);
+            readyToContinue = true;
+        }];
+        TestWebKitAPI::Util::run(&readyToContinue);
+        readyToContinue = false;
+
+        // Fetch records again, this time releasing our reference to the data store while the request is in flight.
+        [dataStore fetchDataRecordsOfTypes:websiteDataTypes.get() completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+            EXPECT_EQ((int)dataRecords.count, 0);
+            readyToContinue = true;
+        }];
+        dataStore = nil;
+    }
+    TestWebKitAPI::Util::run(&readyToContinue);
+    readyToContinue = false;
+
+    @autoreleasepool {
+        auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:websiteDataStoreConfiguration.get()]);
+        [dataStore fetchDataRecordsOfTypes:websiteDataTypes.get() completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+            EXPECT_EQ((int)dataRecords.count, 0);
+            readyToContinue = true;
+        }];
+
+        // Terminate the network process while a query is pending.
+        auto* allProcessPools = [WKProcessPool _allProcessPoolsForTesting];
+        ASSERT_EQ(1U, [allProcessPools count]);
+        auto* processPool = allProcessPools[0];
+        while (![processPool _networkProcessIdentifier])
+            TestWebKitAPI::Util::sleep(0.01);
+        kill([processPool _networkProcessIdentifier], SIGKILL);
+        allProcessPools = nil;
+        dataStore = nil;
+    }
+
+    TestWebKitAPI::Util::run(&readyToContinue);
+    readyToContinue = false;
+}
+
 TEST(WebKit, WebsiteDataStoreEphemeral)
 {
     RetainPtr<WebsiteDataStoreCustomPathsMessageHandler> handler = adoptNS([[WebsiteDataStoreCustomPathsMessageHandler alloc] init]);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to