fix: crash when renderer process crashes while webview is reloading (#46769)

WebView uses WebContentsViewChildFrame, which doesn't have a Focus impl
and triggers a fatal NOTREACHED.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jinli Wu <wujinli@bytedance.com>
This commit is contained in:
trop[bot] 2025-04-25 13:12:54 +02:00 committed by GitHub
parent 0f73bba452
commit d2134f84e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 0 deletions

View file

@ -4101,6 +4101,14 @@ void WebContents::ExitPictureInPicture() {
PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
}
bool WebContents::ShouldFocusPageAfterCrash(content::WebContents* source) {
// WebView uses WebContentsViewChildFrame, which doesn't have a Focus impl
// and triggers a fatal NOTREACHED.
if (is_guest())
return false;
return true;
}
void WebContents::DevToolsSaveToFile(const std::string& url,
const std::string& content,
bool save_as,

View file

@ -755,6 +755,7 @@ class WebContents final : public ExclusiveAccessContext,
content::PictureInPictureResult EnterPictureInPicture(
content::WebContents* web_contents) override;
void ExitPictureInPicture() override;
bool ShouldFocusPageAfterCrash(content::WebContents* source) override;
// InspectableWebContentsDelegate:
void DevToolsSaveToFile(const std::string& url,

View file

@ -1895,6 +1895,28 @@ describe('<webview> tag', function () {
expect(channel).to.equal('onbeforeunload');
});
it('does not crash when renderer process crashes', async function () {
// It takes more time to wait for the rendering process to crash
this.timeout(120000);
await loadWebView(w, {
nodeintegration: 'on',
webpreferences: 'contextIsolation=no',
src: blankPageUrl
});
// Create a crash in the rendering process of a webview
await w.executeJavaScript(`new Promise((resolve, reject) => {
webview.addEventListener('render-process-gone', (e) => resolve({...e}), {once: true})
webview.executeJavaScript('process.crash()', true)
})`);
// Reload the webview and the main process will not crash.
await w.executeJavaScript(`new Promise((resolve, reject) => {
webview.reload()
webview.addEventListener('did-finish-load', () => {
resolve()
})
})`);
});
});
describe('<webview>.goForward()', () => {