-
Notifications
You must be signed in to change notification settings - Fork 15k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: check web_contents() for destroyed WebContents #27815
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like this must be missing situations where we expect web_contents()
to be non-null. There are 100+ references to web_contents()
in this file alone.
Is there some way we could be more safe here?
The The only exception is when user decides to destroy the WebContents during an event, and the Ideally we should refactor the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm... this change makes web_contents()
return nullptr before the api::WebContents
is deleted, and there's an unspecified amount of time in between when web_contents()
starts returning nullptr and when the api::WebContents
is properly deleted. However, we have already called MarkDestroyed()
so any entry point from JS will hit the IsDestroyed() check. Further, since we're no longer observing the WebContents, no WebContentsObserver
methods will be called. That leaves only WebContentsDelegate
methods which can be newly be called in this state when web_contents()
can return null.
There are many many such methods and I suspect that we will introduce new bugs in future where we implement WebContentsDelegate methods expecting that web_contents()
will be non-null, but it isn't always. To wit, here are a few that reference web_contents()
that haven't been addressed in this PR:
WebContents::HandleContextMenu
WebContents::CloseContents
WebContents::OnGoToEntryOffset
I think this PR improves things a bit, but also sheds light on a bunch of problems that are already here.
@@ -1411,7 +1411,7 @@ void WebContents::RenderProcessGone(base::TerminationStatus status) { | |||
Emit("crashed", status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED); | |||
|
|||
// User might destroy WebContents in the crashed event. | |||
if (!weak_this) | |||
if (!weak_this || !web_contents()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this ever be called when web_contents()
is nullptr? RenderProcessGone is a WebContentsObserver method, so if we've called Observe(nullptr)
we shouldn't ever get an observer method call. If Emit("crashed")
destroyed the WebContents, then the weak_this check will be enough to guard this.
@@ -1482,7 +1482,7 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, | |||
// ⚠️WARNING!⚠️ | |||
// Emit() triggers JS which can call destroy() on |this|. It's not safe to | |||
// assume that |this| points to valid memory at this point. | |||
if (is_main_frame && weak_this) | |||
if (is_main_frame && weak_this && web_contents()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here too.
The
For most cases no, but there is an edge case for The call stack is something like this:
The |
Hmmm after writing this down, I realized that the root cause for this crash, is that there is an edge case causing I'll create another PR to cleanup the shutdown routine of WebContents to eliminate this kind of edge cases. But it will be a relatively large refactoring to core shutdown code, and I'm not confident backporting it would not cause other crashes in the stable branches. So I'm in favor of using this PR as a temporary fix to make CI happy, and I'll fix the root cause in the master branch. |
@nornagon I have created #27920 to fix the root cause of the crash, by eliminating the cases that My plan is:
Are you OK with it? |
Hm, alright. Seems better than nothing probably. And any new crashes caused by this PR are ... probably rare? |
No Release Notes |
I have automatically backported this PR to "11-x-y", please check out #27965 |
I have automatically backported this PR to "12-x-y", please check out #27966 |
Description of Change
When Electron is quitting, it may happen that the
content::WebContents
is destroyed whileelectron::api::WebContents
is still alive. This was causing a few CI flakes.Checklist
npm test
passesRelease Notes
Notes: none