Skip to content

[Site Isolation] Fix WKNavigation.LeakCheck#61299

Open
szewai wants to merge 1 commit intoWebKit:mainfrom
szewai:eng/Site-Isolation-Fix-WKNavigation-LeakCheck
Open

[Site Isolation] Fix WKNavigation.LeakCheck#61299
szewai wants to merge 1 commit intoWebKit:mainfrom
szewai:eng/Site-Isolation-Fix-WKNavigation-LeakCheck

Conversation

@szewai
Copy link
Contributor

@szewai szewai commented Mar 25, 2026

f6d9b6f

[Site Isolation] Fix WKNavigation.LeakCheck
https://bugs.webkit.org/show_bug.cgi?id=310670
rdar://173275669

Reviewed by NOBODY (OOPS!).

The test WKNavigation.LeakCheck tries to verify `WKNavigation` or `API::Navigation` will be destroyed when it is not in
use, and here is the flow:
1. Create a WKWebView and loads "example.com" in it => This navigation creates first `WKNavigation` object.
2. Load "webkit.org" in the view => This navigation creates a second `WKNavigation` object.
3. Clear backforward cache.
4. Wait until the first `WKNavigation` object is destroyed.

The test is currently timed out under Site Isolation because the `WKNavigation` object is never destroyed. The idea
behind the test is (see 264449@main): if a page (`WebPageProxy`, including its `SuspendededPageProxy` and
`ProvisionalPageProxy`) stops using a web process (`WebProcessProxy`), it should clear all navigation objects related to
that process (`WebProcessProxy::reportProcessDisassociatedWithPageIfNecessary`). Under Site Isolation, backforward cache
is currently disabled, so the page should be stop using the web process for "example.com" after navigation, and the
navigation object should be destroyed; i.e. the test is still expected to pass.

It turns out to be a bug in `WebProcessProxy::removeWebPage`. So `reportProcessDisassociatedWithPageIfNecessary` is
responsible for notifying `WebPageProxy` about process is no longer in use, and `WebPageProxy` will go ahead to update
navigation state (`WebNavigationState`), which leads to destruction of `WKNavigation` object. In `removeWebPage`,
`reportProcessDisassociatedWithPageIfNecessary` is invoked after page is removed from `globalPageMap()`, so it cannot
find the corresponding page for notificaiton, and the update on navigation state never happens (navigation object is
not destroyed). To fix this, moving invocation of `reportProcessDisassociatedWithPageIfNecessary` to before the removal
on `globalPageMap()`. This patch also adds a new dedicated test for this bug.

Test: WKNavigation.LeakCheckNoPageCache

* Source/WebKit/UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::removeWebPage):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/Navigation.mm:
(runNavigationLeakCheck):
(TEST(WKNavigation, LeakCheck)):
(TEST(WKNavigation, LeakCheckNoPageCache)):

f6d9b6f

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win ✅ 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests loading 🛠 mac-apple
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe ⏳ 🛠 vision-apple
✅ 🧪 ios-wk2-wpt ✅ 🧪 api-mac-debug ✅ 🛠 gtk3-libwebrtc
✅ 🧪 api-ios ✅ 🧪 mac-wk1 ✅ 🛠 gtk
✅ 🛠 ios-safer-cpp ✅ 🧪 mac-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 api-gtk
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🛠 playstation
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2
✅ 🛠 tv ✅ 🛠 mac-safer-cpp
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

https://bugs.webkit.org/show_bug.cgi?id=310670
rdar://173275669

Reviewed by NOBODY (OOPS!).

The test WKNavigation.LeakCheck tries to verify `WKNavigation` or `API::Navigation` will be destroyed when it is not in
use, and here is the flow:
1. Create a WKWebView and loads "example.com" in it => This navigation creates first `WKNavigation` object.
2. Load "webkit.org" in the view => This navigation creates a second `WKNavigation` object.
3. Clear backforward cache.
4. Wait until the first `WKNavigation` object is destroyed.

The test is currently timed out under Site Isolation because the `WKNavigation` object is never destroyed. The idea
behind the test is (see 264449@main): if a page (`WebPageProxy`, including its `SuspendededPageProxy` and
`ProvisionalPageProxy`) stops using a web process (`WebProcessProxy`), it should clear all navigation objects related to
that process (`WebProcessProxy::reportProcessDisassociatedWithPageIfNecessary`). Under Site Isolation, backforward cache
is currently disabled, so the page should be stop using the web process for "example.com" after navigation, and the
navigation object should be destroyed; i.e. the test is still expected to pass.

It turns out to be a bug in `WebProcessProxy::removeWebPage`. So `reportProcessDisassociatedWithPageIfNecessary` is
responsible for notifying `WebPageProxy` about process is no longer in use, and `WebPageProxy` will go ahead to update
navigation state (`WebNavigationState`), which leads to destruction of `WKNavigation` object. In `removeWebPage`,
`reportProcessDisassociatedWithPageIfNecessary` is invoked after page is removed from `globalPageMap()`, so it cannot
find the corresponding page for notificaiton, and the update on navigation state never happens (navigation object is
not destroyed). To fix this, moving invocation of `reportProcessDisassociatedWithPageIfNecessary` to before the removal
on `globalPageMap()`. This patch also adds a new dedicated test for this bug.

Test: WKNavigation.LeakCheckNoPageCache

* Source/WebKit/UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::removeWebPage):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/Navigation.mm:
(runNavigationLeakCheck):
(TEST(WKNavigation, LeakCheck)):
(TEST(WKNavigation, LeakCheckNoPageCache)):
@szewai szewai self-assigned this Mar 25, 2026
@szewai szewai added the New Bugs Unclassified bugs are placed in this component until the correct component can be determined. label Mar 25, 2026
@szewai szewai marked this pull request as ready for review March 25, 2026 16:19
@szewai szewai requested a review from cdumez as a code owner March 25, 2026 16:19
@szewai szewai requested a review from pvollan March 25, 2026 17:36
@@ -4351,24 +4352,27 @@ HTTPServer httpServer({
EXPECT_WK_STREQ(@"", [webView URL].absoluteString);
}

TEST(WKNavigation, LeakCheck)
enum class ShouldEnablePageCache : bool { No, Yes };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: should we use ShouldEnableBackForwardCache?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New Bugs Unclassified bugs are placed in this component until the correct component can be determined.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants