⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 273695 in webkit


Ignore:
Timestamp:
Mar 1, 2021, 3:07:58 PM (6 years ago)
Author:
Chris Dumez
Message:

Crash under WebProcessPool::pageBeginUsingWebsiteDataStore()
​https://bugs.webkit.org/show_bug.cgi?id=222574
<rdar://68340471>

Reviewed by Geoffrey Garen.

Source/WebKit:

The issue was that when WebProcessProxy::requestTermination() was called (e.g. process is killed by WebKit
for using too much memory), we would fail to remove the process from the WebProcessCache. Because the
terminated would stay in the cache (even though WebProcessProxy::shutDown() was called), we could potentially
try and use it later on for a navigation to the same domain. This would lead to crashes because
WebProcessProxy::shutDown() has already been called.

Note that we were previously correctly removing the process from the cache in case of a proper crash, inside
WebProcessProxy::processDidTerminateOrFailedToLaunch(). I have moved the logic to remove from the cache
from processDidTerminateOrFailedToLaunch() to shutDown() to avoid similar issues in the future.

  • UIProcess/API/Cocoa/WKProcessPool.mm:

(-[WKProcessPool _requestWebProcessTermination:]):

  • UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::shutDown):
(WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch):

Tools:

Add API test coverage.

  • TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r273694 r273695  
     12021-03-01  Chris Dumez  <cdumez@apple.com>
     2
     3        Crash under WebProcessPool::pageBeginUsingWebsiteDataStore()
     4        https://bugs.webkit.org/show_bug.cgi?id=222574
     5        <rdar://68340471>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        The issue was that when WebProcessProxy::requestTermination() was called (e.g. process is killed by WebKit
     10        for using too much memory), we would fail to remove the process from the WebProcessCache. Because the
     11        terminated would stay in the cache (even though WebProcessProxy::shutDown() was called), we could potentially
     12        try and use it later on for a navigation to the same domain. This would lead to crashes because
     13        WebProcessProxy::shutDown() has already been called.
     14
     15        Note that we were previously correctly removing the process from the cache in case of a proper crash, inside
     16        WebProcessProxy::processDidTerminateOrFailedToLaunch(). I have moved the logic to remove from the cache
     17        from processDidTerminateOrFailedToLaunch() to shutDown() to avoid similar issues in the future.
     18
     19        * UIProcess/API/Cocoa/WKProcessPool.mm:
     20        (-[WKProcessPool _requestWebProcessTermination:]):
     21        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
     22        * UIProcess/WebProcessProxy.cpp:
     23        (WebKit::WebProcessProxy::shutDown):
     24        (WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch):
     25
    1262021-03-01  Stephan Szabo  <stephan.szabo@sony.com>
    227
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm

    r273276 r273695  
    388388}
    389389
     390- (BOOL)_requestWebProcessTermination:(pid_t)pid
     391{
     392    for (auto& process : _processPool->processes()) {
     393        if (process->processIdentifier() == pid)
     394            process->requestTermination(WebKit::ProcessTerminationReason::RequestedByClient);
     395        return YES;
     396    }
     397    return NO;
     398}
     399
    390400- (void)_makeNextWebProcessLaunchFailForTesting
    391401{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h

    r271813 r273695  
    111111- (void)_setUseSeparateServiceWorkerProcess:(BOOL)forceServiceWorkerProcess WK_API_AVAILABLE(macos(10.15.4), ios(13.4));
    112112- (pid_t)_gpuProcessIdentifier WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     113- (BOOL)_requestWebProcessTermination:(pid_t)pid WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    113114
    114115// Test only. Returns web processes running web pages (does not include web processes running service workers)
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r273657 r273695  
    449449    RELEASE_ASSERT(isMainThreadOrCheckDisabled());
    450450
     451    if (m_isInProcessCache) {
     452        processPool().webProcessCache().removeProcess(*this, WebProcessCache::ShouldShutDownProcess::No);
     453        ASSERT(!m_isInProcessCache);
     454    }
     455
    451456    shutDownProcess();
    452457
    … …  
    867872    for (auto& callback : isResponsiveCallbacks)
    868873        callback(false);
    869 
    870     if (m_isInProcessCache) {
    871         processPool().webProcessCache().removeProcess(*this, WebProcessCache::ShouldShutDownProcess::No);
    872         ASSERT(!m_isInProcessCache);
    873     }
    874874
    875875    if (isStandaloneServiceWorkerProcess())
  • trunk/Tools/ChangeLog

    r273683 r273695  
     12021-03-01  Chris Dumez  <cdumez@apple.com>
     2
     3        Crash under WebProcessPool::pageBeginUsingWebsiteDataStore()
     4        https://bugs.webkit.org/show_bug.cgi?id=222574
     5        <rdar://68340471>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
     12
    1132021-03-01  Sam Weinig  <weinig@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

    r273194 r273695  
    36913691}
    36923692
     3693TEST(ProcessSwap, ProcessCrashedWhileInTheCache)
     3694{
     3695    auto processPoolConfiguration = psonProcessPoolConfiguration();
     3696    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     3697
     3698    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     3699    [webViewConfiguration setProcessPool:processPool.get()];
     3700    auto handler = adoptNS([[PSONScheme alloc] init]);
     3701    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
     3702
     3703    auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
     3704    [navigationDelegate setDidFinishNavigation:^(WKWebView *, WKNavigation *) {
     3705        done = true;
     3706    }];
     3707
     3708    int webkitPID = 0;
     3709
     3710    @autoreleasepool {
     3711        auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     3712        [webView setNavigationDelegate:navigationDelegate.get()];
     3713
     3714        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     3715
     3716        [webView loadRequest:request];
     3717        TestWebKitAPI::Util::run(&done);
     3718        done = false;
     3719        webkitPID = [webView _webProcessIdentifier];
     3720    }
     3721
     3722    while ([processPool _processCacheSize] != 1)
     3723        TestWebKitAPI::Util::sleep(0.1);
     3724
     3725    kill(webkitPID, 9);
     3726
     3727    while ([processPool _processCacheSize])
     3728        TestWebKitAPI::Util::sleep(0.1);
     3729
     3730    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     3731    [webView setNavigationDelegate:navigationDelegate.get()];
     3732
     3733    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     3734
     3735    [webView loadRequest:request];
     3736    TestWebKitAPI::Util::run(&done);
     3737    done = false;
     3738
     3739    EXPECT_NE(webkitPID, [webView _webProcessIdentifier]);
     3740}
     3741
     3742TEST(ProcessSwap, ProcessTerminatedWhileInTheCache)
     3743{
     3744    auto processPoolConfiguration = psonProcessPoolConfiguration();
     3745    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     3746
     3747    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     3748    [webViewConfiguration setProcessPool:processPool.get()];
     3749    auto handler = adoptNS([[PSONScheme alloc] init]);
     3750    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
     3751
     3752    auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
     3753    [navigationDelegate setDidFinishNavigation:^(WKWebView *, WKNavigation *) {
     3754        done = true;
     3755    }];
     3756
     3757    int webkitPID = 0;
     3758
     3759    @autoreleasepool {
     3760        auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     3761        [webView setNavigationDelegate:navigationDelegate.get()];
     3762
     3763        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     3764
     3765        [webView loadRequest:request];
     3766        TestWebKitAPI::Util::run(&done);
     3767        done = false;
     3768        webkitPID = [webView _webProcessIdentifier];
     3769    }
     3770
     3771    while ([processPool _processCacheSize] != 1)
     3772        TestWebKitAPI::Util::sleep(0.1);
     3773
     3774    EXPECT_TRUE([processPool _requestWebProcessTermination:webkitPID]);
     3775    TestWebKitAPI::Util::spinRunLoop(100);
     3776
     3777    EXPECT_EQ(0U, [processPool _processCacheSize]);
     3778
     3779    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     3780    [webView setNavigationDelegate:navigationDelegate.get()];
     3781
     3782    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     3783
     3784    [webView loadRequest:request];
     3785    TestWebKitAPI::Util::run(&done);
     3786    done = false;
     3787
     3788    EXPECT_NE(webkitPID, [webView _webProcessIdentifier]);
     3789}
     3790
    36933791TEST(ProcessSwap, UseWebProcessCacheForLoadInNewView)
    36943792{
Note: See TracChangeset for help on using the changeset viewer.