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

Changeset 285720 in webkit


Ignore:
Timestamp:
Nov 12, 2021, 8:18:51 AM (5 years ago)
Author:
Chris Dumez
Message:

WebKit is unable to recover if a WebProcess gets terminated while it is launching
https://bugs.webkit.org/show_bug.cgi?id=233001
<rdar://85302938>

Reviewed by Brent Fulgham.

Source/WebKit:

While investigating <rdar://83941760>, I found that the WebAuthn Process would get
jetsammed, which would cause us to call WebProcessPool::terminateAllWebContentProcesses().
I also noticed that if one of these WebProcesses was still launching at the time
of the termination, then the WebProcessProxy / WebPageProxy would keep thinking the
WebProcess is still launching and would never attempt to relaunch it. This would result
in a blank and unresponsive WKWebView which wouldn't be able to do any loads.

The issue was due to ProcessLauncher::terminateProcess() calling invalidate(), which
it would not only terminate the XPC connection, it would also null out m_client. As a
result, we wouldn't notify the client that the process failed to launch. To address
the issue, I move the XPC connection termination logic out of invalidate() and into
its own terminateXPCConnection() function. I then called terminateXPCConnection()
instead of invalidate() inside ProcessLauncher::terminateProcess().

  • UIProcess/API/Cocoa/WKProcessPool.mm:

(-[WKProcessPool _terminateAllWebContentProcesses]):

  • UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
  • UIProcess/Launcher/ProcessLauncher.cpp:

(WebKit::ProcessLauncher::invalidate):

  • UIProcess/Launcher/ProcessLauncher.h:
  • UIProcess/Launcher/mac/ProcessLauncherMac.mm:

(WebKit::ProcessLauncher::terminateProcess):
(WebKit::ProcessLauncher::platformInvalidate):
(WebKit::ProcessLauncher::terminateXPCConnection):

Tools:

Add API test coverage, this test was timing out before the fix.

  • TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm:

(TEST):

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r285717 r285720  
     12021-11-12  Chris Dumez  <cdumez@apple.com>
     2
     3        WebKit is unable to recover if a WebProcess gets terminated while it is launching
     4        https://bugs.webkit.org/show_bug.cgi?id=233001
     5        <rdar://85302938>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        While investigating <rdar://83941760>, I found that the WebAuthn Process would get
     10        jetsammed, which would cause us to call WebProcessPool::terminateAllWebContentProcesses().
     11        I also noticed that if one of these WebProcesses was still launching at the time
     12        of the termination, then the WebProcessProxy / WebPageProxy would keep thinking the
     13        WebProcess is still launching and would never attempt to relaunch it. This would result
     14        in a blank and unresponsive WKWebView which wouldn't be able to do any loads.
     15
     16        The issue was due to ProcessLauncher::terminateProcess() calling invalidate(), which
     17        it would not only terminate the XPC connection, it would also null out m_client. As a
     18        result, we wouldn't notify the client that the process failed to launch. To address
     19        the issue, I move the XPC connection termination logic out of invalidate() and into
     20        its own terminateXPCConnection() function. I then called terminateXPCConnection()
     21        instead of invalidate() inside ProcessLauncher::terminateProcess().
     22
     23        * UIProcess/API/Cocoa/WKProcessPool.mm:
     24        (-[WKProcessPool _terminateAllWebContentProcesses]):
     25        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
     26        * UIProcess/Launcher/ProcessLauncher.cpp:
     27        (WebKit::ProcessLauncher::invalidate):
     28        * UIProcess/Launcher/ProcessLauncher.h:
     29        * UIProcess/Launcher/mac/ProcessLauncherMac.mm:
     30        (WebKit::ProcessLauncher::terminateProcess):
     31        (WebKit::ProcessLauncher::platformInvalidate):
     32        (WebKit::ProcessLauncher::terminateXPCConnection):
     33
    1342021-11-12  Chris Dumez  <cdumez@apple.com>
    235
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm

    r285047 r285720  
    591591}
    592592
     593- (void)_terminateAllWebContentProcesses
     594{
     595    _processPool->terminateAllWebContentProcesses();
     596}
     597
    593598@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h

    r282218 r285720  
    9999- (pid_t)_prewarmedProcessIdentifier WK_API_AVAILABLE(macos(10.15), ios(13.0));
    100100
     101- (void)_terminateAllWebContentProcesses;
     102
    101103// Test only.
    102104- (size_t)_webProcessCount WK_API_AVAILABLE(macos(10.13), ios(11.0));
  • trunk/Source/WebKit/UIProcess/Launcher/ProcessLauncher.cpp

    r249274 r285720  
    6262void ProcessLauncher::invalidate()
    6363{
    64     m_client = 0;
     64    m_client = nullptr;
    6565    platformInvalidate();
    6666}
  • trunk/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h

    r285594 r285720  
    123123    void platformInvalidate();
    124124
     125#if PLATFORM(COCOA)
     126    void terminateXPCConnection();
     127#endif
     128
    125129    Client* m_client;
    126130
  • trunk/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm

    r285594 r285720  
    323323{
    324324    if (m_isLaunching) {
    325         invalidate();
     325        terminateXPCConnection();
    326326        return;
    327327    }
     
    336336void ProcessLauncher::platformInvalidate()
    337337{
     338    terminateXPCConnection();
     339}
     340
     341void ProcessLauncher::terminateXPCConnection()
     342{
    338343    if (!m_xpcConnection)
    339344        return;
  • trunk/Tools/ChangeLog

    r285717 r285720  
     12021-11-12  Chris Dumez  <cdumez@apple.com>
     2
     3        WebKit is unable to recover if a WebProcess gets terminated while it is launching
     4        https://bugs.webkit.org/show_bug.cgi?id=233001
     5        <rdar://85302938>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Add API test coverage, this test was timing out before the fix.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm:
     12        (TEST):
     13
    1142021-11-12  Chris Dumez  <cdumez@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebProcessTerminate.mm

    r242339 r285720  
    3030#import "TestNavigationDelegate.h"
    3131
     32#import <WebKit/WKProcessPoolPrivate.h>
    3233#import <WebKit/WKWebViewPrivate.h>
    3334#import <WebKit/WebKit.h>
     
    4849    EXPECT_TRUE(pid != pid2);
    4950}
     51
     52TEST(WebKit, TerminateAllProcessesDuringLaunch)
     53{
     54    auto webView = adoptNS([WKWebView new]);
     55
     56    // Initiate a load to make sure the process actually launches.
     57    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
     58
     59    // Call terminateAllProcesses while the process is still launching.
     60    [webView.get().configuration.processPool _terminateAllWebContentProcesses];
     61
     62    TestWebKitAPI::Util::sleep(0.5);
     63
     64    // The WKWebView should be able to recover from the WebProcess termination and navigation should succeed.
     65    [webView loadHTMLString:@"test" baseURL:nil];
     66    [webView _test_waitForDidFinishNavigation];
     67}
Note: See TracChangeset for help on using the changeset viewer.