Skip to content
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: account for potentially swapped FrameTreeNodeId in WebFrameMain #41538

Merged
merged 2 commits into from Mar 14, 2024

Conversation

codebytere
Copy link
Member

@codebytere codebytere commented Mar 7, 2024

Description of Change

Refs https://issues.chromium.org/issues/40169570
Refs #30076

Fixes a crash in WebFrameMain::FromRenderFrameHost that could occur when a given RenderFrameHost's FrameTreeNode is invalid. In #30076 we addressed cross-origin navigation disposing WebFrameMain instances by mapping FrameTreeNode ids to WebFrameMains. At the time, a RenderFrameHost's FrameTreeNode was constant for the lifetime of the RenderFrameHost - that's no longer the case. With prerendering and bfcache, a RenderFrameHost can travel from one FrameTreeNode to another one during prerender activation.

We should migrate our mapping logic away from 1:1 FrameTreeNode -> RenderFrameHost but this addresses it crashing in the short term.

Details

Electron Framework
content::RenderFrameHostImpl::GetFrameTreeNodeId() const frame_tree_node.h:141
Electron Framework
electron::api::WebFrameMain::FromRenderFrameHost(content::RenderFrameHost*) electron_api_web_frame_main.cc:80
Electron Framework
electron::api::WebFrameMain::From(v8::Isolate*, content::RenderFrameHost*) electron_api_web_frame_main.cc:434
Electron Framework
electron::api::WebContents::FindReply(content::WebContents*, int, int, gfx::Rect const&, int, bool, content::RenderFrameHost*) electron_api_web_contents.cc:1512
Electron Framework
content::WebContentsImpl::NotifyFindReply(int, int, gfx::Rect const&, int, bool, content::RenderFrameHost*) web_contents_impl.cc:8965
Electron Framework
content::FindRequestManager::FinalUpdateReceived(int, content::RenderFrameHost*) find_request_manager.cc:914
Electron Framework
content::FindRequestManager::HandleFinalUpdateForFrame(content::RenderFrameHostImpl*, int) find_request_manager.cc:451
Electron Framework
blink::mojom::FindInPageClientStubDispatch::Accept(blink::mojom::FindInPageClient*, mojo::Message*) find_in_page.mojom.cc:825
Electron Framework
mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) interface_endpoint_client.cc:1016
Electron Framework
mojo::MessageDispatcher::Accept(mojo::Message*) message_dispatcher.cc:43
Electron Framework
mojo::InterfaceEndpointClient::HandleIncomingMessage(mojo::Message*) interface_endpoint_client.cc:701
Electron Framework
mojo::internal::MultiplexRouter::Accept(mojo::Message*) multiplex_router.cc:1096
Electron Framework
mojo::MessageDispatcher::Accept(mojo::Message*) message_dispatcher.cc:43
Electron Framework
mojo::Connector::DispatchMessage(mojo::ScopedHandleBase<mojo::MessageHandle>) connector.cc:561
Electron Framework
base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(char const*, unsigned int), base::internal::UnretainedWrapper<mojo::Connector, base::unretained_traits::MayNotDangle, (base::RawPtrTraits)0>, base::internal::UnretainedWrapper<char const, base::unretained_traits::MayNotDangle, (base::RawPtrTraits)0>>, void (unsigned int)>::Run(base::internal::BindStateBase*, unsigned int) connector.cc:618
Electron Framework
base::internal::Invoker<base::internal::BindState<void (*)(base::RepeatingCallback<void (unsigned int)> const&, unsigned int, mojo::HandleSignalsState const&), base::RepeatingCallback<void (unsigned int)>>, void (unsigned int, mojo::HandleSignalsState const&)>::Run(base::internal::BindStateBase*, unsigned int, mojo::HandleSignalsState const&) callback.h:333
Electron Framework
base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, mojo::HandleSignalsState const&), base::WeakPtr<mojo::SimpleWatcher>, int, unsigned int, mojo::HandleSignalsState>, void ()>::RunOnce(base::internal::BindStateBase*) callback.h:333
Electron Framework
base::TaskAnnotator::RunTaskImpl(base::PendingTask&) callback.h:152
Electron Framework
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*) task_annotator.h:89
Electron Framework
non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() thread_controller_with_message_pump_impl.cc:345
Electron Framework
invocation function for block in base::MessagePumpCFRunLoopBase::RunWorkSource(void*) message_pump_apple.mm:416
Electron Framework
invocation function for block in base::MessagePumpCFRunLoopBase::RunWorkSource(void*) message_pump_apple.mm:416
Electron Framework
base::apple::CallWithEHFrame(void () block_pointer)
CoreFoundation
0x8da8f9d8 + 514520

Checklist

Release Notes

Notes: none

@codebytere codebytere added semver/patch backwards-compatible bug fixes target/28-x-y PR should also be added to the "28-x-y" branch. target/29-x-y PR should also be added to the "29-x-y" branch. target/30-x-y PR should also be added to the "30-x-y" branch. labels Mar 7, 2024
@electron-cation electron-cation bot added the new-pr 🌱 PR opened in the last 24 hours label Mar 7, 2024
@codebytere codebytere force-pushed the speculative-crash-fix-webframe branch from 3dd4a9d to 5234415 Compare March 7, 2024 09:22
@codebytere codebytere changed the title fix: account for potentially swapped FrameTreeNodeId in WebFrameMain fix: account for potentially swapped FrameTreeNodeId in WebFrameMain Mar 7, 2024
@electron-cation electron-cation bot removed the new-pr 🌱 PR opened in the last 24 hours label Mar 8, 2024
@codebytere codebytere requested a review from zcbenz March 12, 2024 08:57

// TODO(codebytere): remove after refactoring away from FrameTreeNodeId as map
// key.
auto* ftn =
Copy link
Member

Choose a reason for hiding this comment

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

Does the current map get updated when ftn gets swapped for the pre-rendering case ? What is the alternative here, should we change to use GlobalRenderFrameHostToken as the map identifier ?

Copy link
Member Author

Choose a reason for hiding this comment

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

No - at the moment it doesn't since it was written for the assumption that wouldn't happen. I do think we can use GlobalRenderFrameHostToken instead; i can refactor it in this PR but i wasn't sure how much time it'd take to look into it more so I thought i'd mitigate a hard crash before doing so. Do you have a preference?

Copy link
Member

Choose a reason for hiding this comment

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

Lets do it as follow-up, we might want to change to track ftn directly rather than the underlying rfh so this needs further discussion.

@samuelmaddock
Copy link
Member

samuelmaddock commented Mar 13, 2024

Looking at the call stack, I'm not seeing where a frame is being created in WebContents::FindReply. Is this part of a fork?

Electron Framework
content::RenderFrameHostImpl::GetFrameTreeNodeId() const frame_tree_node.h:141
Electron Framework
electron::api::WebFrameMain::FromRenderFrameHost(content::RenderFrameHost*) electron_api_web_frame_main.cc:80
Electron Framework
electron::api::WebFrameMain::From(v8::Isolate*, content::RenderFrameHost*) electron_api_web_frame_main.cc:434
Electron Framework
electron::api::WebContents::FindReply(content::WebContents*, int, int, gfx::Rect const&, int, bool, content::RenderFrameHost*) electron_api_web_contents.cc:1512
Electron Framework
content::WebContentsImpl::NotifyFindReply(int, int, gfx::Rect const&, int, bool, content::RenderFrameHost*) web_contents_impl.cc:8965
Electron Framework

The intent I had with designing WebFrameMain was to essentially track a corresponding <iframe> in the renderer process. With that in mind, I think it should still be aware of FrameTreeNode/FTN (which more closely represents frames over the transient RFH) in some capacity. The unfortunate part of this design is that FTNs are not a public API. Open to discussing more beyond this PR.

That being said, I think merging this to protect against the hard crash is fine for now.

@deepak1556
Copy link
Member

Yeah its from a fork which has the find API based on #28274

Copy link
Member

@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

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

LGTM

@codebytere
Copy link
Member Author

Failures are known flakes.

@codebytere codebytere merged commit 1bfd3e0 into main Mar 14, 2024
15 of 17 checks passed
@codebytere codebytere deleted the speculative-crash-fix-webframe branch March 14, 2024 08:50
Copy link

release-clerk bot commented Mar 14, 2024

No Release Notes

trop bot added a commit that referenced this pull request Mar 14, 2024
…in` (#41538)

fix: account for potentially swapped FrameTreeNodeId in WebFrameMain

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
@trop
Copy link
Contributor

trop bot commented Mar 14, 2024

I have automatically backported this PR to "28-x-y", please check out #41592

@trop
Copy link
Contributor

trop bot commented Mar 14, 2024

I have automatically backported this PR to "29-x-y", please check out #41593

@trop
Copy link
Contributor

trop bot commented Mar 14, 2024

I have automatically backported this PR to "30-x-y", please check out #41594

@trop trop bot added in-flight/30-x-y and removed target/29-x-y PR should also be added to the "29-x-y" branch. target/30-x-y PR should also be added to the "30-x-y" branch. labels Mar 14, 2024
jkleinsc pushed a commit that referenced this pull request Mar 14, 2024
…in` (#41592)

fix: account for potentially swapped `FrameTreeNodeId` in `WebFrameMain` (#41538)

fix: account for potentially swapped FrameTreeNodeId in WebFrameMain

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
@trop trop bot added merged/28-x-y PR was merged to the "28-x-y" branch. merged/30-x-y PR was merged to the "30-x-y" branch. merged/29-x-y PR was merged to the "29-x-y" branch. and removed in-flight/28-x-y in-flight/30-x-y in-flight/29-x-y labels Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged/28-x-y PR was merged to the "28-x-y" branch. merged/29-x-y PR was merged to the "29-x-y" branch. merged/30-x-y PR was merged to the "30-x-y" branch. semver/patch backwards-compatible bug fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants