Summary: | REGRESSION(r268097): Calling processDidTerminate delegate asynchronously is risky compatibility-wise | ||||||
---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | Chris Dumez <cdumez> | ||||
Component: | WebKit2 | Assignee: | Chris Dumez <cdumez> | ||||
Status: | RESOLVED FIXED | ||||||
Severity: | Normal | CC: | achristensen, beidson, cgarcia, darin, ggaren, luming_yin, mcatanzaro, thorton, webkit-bug-importer | ||||
Priority: | P2 | Keywords: | InRadar | ||||
Version: | WebKit Nightly Build | ||||||
Hardware: | Unspecified | ||||||
OS: | Unspecified | ||||||
See Also: | https://bugs.webkit.org/show_bug.cgi?id=222809 | ||||||
Bug Depends on: | |||||||
Bug Blocks: | 217407 | ||||||
Attachments: |
|
Description
Chris Dumez
2021-02-16 17:32:52 PST
Created attachment 420567 [details]
Patch
Comment on attachment 420567 [details]
Patch
Thanks!
commit-queue failed to commit attachment 420567 [details] to WebKit repository. To retry, please set cq+ flag again.
Committed r272990: <https://commits.webkit.org/r272990> All reviewed patches have been landed. Closing bug and clearing flags on attachment 420567 [details]. Hi Chris, it looks like this didn't actually fix Epiphany. The problem is here in WebProcessProxy::processDidTerminateOrFailedToLaunch: for (auto& page : pages) page->resetStateAfterProcessTermination(reason); for (auto& provisionalPage : provisionalPages) { if (provisionalPage) provisionalPage->processDidTerminate(); } for (auto& page : pages) page->dispatchProcessDidTerminate(reason); WebPageProxy::resetStateAfterProcessTermination calls WebPageProxy::resetStateAfterProcessExited, which resets its m_pageLoadState, here: if (terminationReason != ProcessTerminationReason::NavigationSwap) { PageLoadState::Transaction transaction = m_pageLoadState.transaction(); m_pageLoadState.reset(transaction); } That clears the page's URI, and as you see above it happens just before WebProcessProxy calls WebPageProxy::dispatchProcessDidTerminate. To avoid this regression, we would need to ensure the page's URI doesn't get reset until *after* WebPageProxy::dispatchProcessDidTerminate. Again, easy to workaround in the client, but would be nice if we didn't need to. How bad would it be to move the code that resets the PageLoadState to a later point? (In reply to Michael Catanzaro from comment #6) > Hi Chris, it looks like this didn't actually fix Epiphany. The problem is > here in WebProcessProxy::processDidTerminateOrFailedToLaunch: > > for (auto& page : pages) > page->resetStateAfterProcessTermination(reason); > > for (auto& provisionalPage : provisionalPages) { > if (provisionalPage) > provisionalPage->processDidTerminate(); > } > > for (auto& page : pages) > page->dispatchProcessDidTerminate(reason); > > WebPageProxy::resetStateAfterProcessTermination calls > WebPageProxy::resetStateAfterProcessExited, which resets its > m_pageLoadState, here: > > if (terminationReason != ProcessTerminationReason::NavigationSwap) { > PageLoadState::Transaction transaction = > m_pageLoadState.transaction(); > m_pageLoadState.reset(transaction); > } > > That clears the page's URI, and as you see above it happens just before > WebProcessProxy calls WebPageProxy::dispatchProcessDidTerminate. To avoid > this regression, we would need to ensure the page's URI doesn't get reset > until *after* WebPageProxy::dispatchProcessDidTerminate. > > Again, easy to workaround in the client, but would be nice if we didn't need > to. How bad would it be to move the code that resets the PageLoadState to a > later point? I don't understand why this is a regression from my original change then though. We always called resetStateAfterProcessExited() *before* notifying the client. (In reply to Chris Dumez from comment #7) > (In reply to Michael Catanzaro from comment #6) > > Hi Chris, it looks like this didn't actually fix Epiphany. The problem is > > here in WebProcessProxy::processDidTerminateOrFailedToLaunch: > > > > for (auto& page : pages) > > page->resetStateAfterProcessTermination(reason); > > > > for (auto& provisionalPage : provisionalPages) { > > if (provisionalPage) > > provisionalPage->processDidTerminate(); > > } > > > > for (auto& page : pages) > > page->dispatchProcessDidTerminate(reason); > > > > WebPageProxy::resetStateAfterProcessTermination calls > > WebPageProxy::resetStateAfterProcessExited, which resets its > > m_pageLoadState, here: > > > > if (terminationReason != ProcessTerminationReason::NavigationSwap) { > > PageLoadState::Transaction transaction = > > m_pageLoadState.transaction(); > > m_pageLoadState.reset(transaction); > > } > > > > That clears the page's URI, and as you see above it happens just before > > WebProcessProxy calls WebPageProxy::dispatchProcessDidTerminate. To avoid > > this regression, we would need to ensure the page's URI doesn't get reset > > until *after* WebPageProxy::dispatchProcessDidTerminate. > > > > Again, easy to workaround in the client, but would be nice if we didn't need > > to. How bad would it be to move the code that resets the PageLoadState to a > > later point? > > I don't understand why this is a regression from my original change then > though. We always called resetStateAfterProcessExited() *before* notifying > the client. Oh, I think it is because there was this in scope: PageLoadState::Transaction transaction = m_pageLoadState.transaction(); So even though we cleared the URL before call the client, the change would not take effect until after the transaction gets destroyed, which was *after* we called the client.. So it seems I indeed changed behavior here :/ Chris posted a fix in bug #222809. |