Bug 198794 - [PSON] Client can receive a didFailProvisionalNavigation without ever receiving a didStartProvisionalNavigation
Summary: [PSON] Client can receive a didFailProvisionalNavigation without ever receivi...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-06-12 10:59 PDT by Ali Juma
Modified: 2019-06-12 10:59 PDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ali Juma 2019-06-12 10:59:42 PDT
On Chrome on iOS 12.2+, we're seeing cases where we get a didFailProvisionalNavigation call for a WKNavigation* we've never seen before. This was causing crashes for us since in our didFailProvisionalNavigation handler we would assume we'd find the given WKNavigation in our internal hash map of known navigations. The relevant part of the crash stack is:

0x00000001b63fc140 (WebKit + 0x00170140)	WebKit::NavigationState::NavigationClient::didFailProvisionalNavigationWithError(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, WebCore::ResourceError const&, API::Object*)
0x00000001b645fc2c (WebKit + 0x001d3c2c)	WebKit::WebPageProxy::didFailProvisionalLoadForFrameShared(WTF::Ref<WebKit::WebProcessProxy, WTF::DumbPtrTraits<WebKit::WebProcessProxy> >&&, unsigned long long, WebCore::SecurityOriginData const&, unsigned long long, WTF::String const&, WebCore::ResourceError const&, WebKit::UserData const&)
0x00000001b64015c4 (WebKit + 0x001755c4)	WebKit::ProvisionalPageProxy::didFailProvisionalLoadForFrame(unsigned long long, WebCore::SecurityOriginData const&, unsigned long long, WTF::String const&, WebCore::ResourceError const&, WebKit::UserData const&)
0x00000001b640131c (WebKit + 0x0017531c)	WebKit::ProvisionalPageProxy::cancel()
0x00000001b645a388 (WebKit + 0x001ce388)	WebKit::WebPageProxy::continueNavigationInNewProcess(API::Navigation&, std::__1::unique_ptr<WebKit::SuspendedPageProxy, std::__1::default_delete<WebKit::SuspendedPageProxy> >&&, WTF::Ref<WebKit::WebProcessProxy, WTF::DumbPtrTraits<WebKit::WebProcessProxy> >&&, WebKit::ProcessSwapRequestedByClient, WTF::Optional<WebKit::WebsitePoliciesData>&&)

It appears that we're running into a sequence where:
1) There's a ProvisionalPageProxy for which we haven't yet received a didStartProvisionalNavigation.
2) Another cross-origin navigation is initiated.
3) The client receives a decidePolicyForNavigationAction for this new navigation, and allows it.
4) On receiving the policy decision, we wind up in the above stack, where we first need to cancel and destroy the existing ProvisionalPageProxy.

The confusing part is that if we're in the above stack, it means m_provisionalLoadURL was non-empty (or else ProvisionalPageProxy::cancel would have earlied-out), which means that ProvisionalPageProxy::didStartProvisionalLoadForFrame was reached, and this should end up calling into the client unless it earlies out because we're following a server-side redirect, which in turn should mean we previously sent the client a didStartProvisionalNavigation.

So it's not at all clear where things are going wrong.

Suspecting this is PSON-related because the crash stacks always include WebPageProxy::continueNavigationInNewProcess and we're not seeing an equivalent crash on iOS 12.0 or 12.1.