OnBrowserDestroyed() called after Frame.LoadURL()

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

OnBrowserDestroyed() called after Frame.LoadURL()

Postby Czarek » Wed Sep 18, 2013 10:20 am

Hi Marshall,

After I make a call to browser->GetMainFrame()->LoadURL(), I see in the logs that
CefRenderProcessHandler::OnBrowserDestroyed() is being called. This call destroys
javascript bindings for given browser in my app and is not an expected behavior. The
LifespanHandler::OnBeforeClose() is not being called in this case. Also, the navigateUrl
passed to CreateBrowserSync() is "google.com", and the url passed to LoadURL() is
"google.com" as well.

Why is OnBrowserDestroyed() being called, is this some bug?

EDIT. OnBrowserDestroyed() is sometimes not being called, looks like a random behavior.

EDIT 2. I tried to fix it by setting javascript bindings again after the call to LoadURL(),
but seems there is an another bug in CEF that makes this impossible in an appropriate
timing. The problem is when calling CefBrowser.GetFrameIdentifiers(), it returns a
vector with frameId=0, which is an invalid frame. I'm calling GetFrameIdentifiers in
CefRenderProcessHandler::OnProcessMessageReceived().

EDIT 3. The fix for GetFrameIdentifiers() bug is to call browser->GetMainFrame()->GetIdentifier(),
then I get correct id. After the LoadURL() and OnBrowserDestroyed() callback is called, the
browser window seems to lose the focus and I have to call SendFocusEvent() again.

EDIT 4. When website contains many iframes then the GetFrameIdentifiers() bug is a serious problem.
It seems to always return an empty vector with all frame identifiers equal to 0. I've tried to post a
delayed task to call GetFrameIdentifiers at a later time, but it's the same, GetFrameIdentifiers still
doesn't work.

EDIT 5. I've found a fix to the GetFrameIdentifiers() problem. Using GetFrameNames() instead.
Though its documentation should be updated:

https://code.google.com/p/chromiumembed ... r=1448#176
Code: Select all
  ///
  // Returns the names of all existing frames.
  ///
  /*--cef()--*/
  virtual void GetFrameNames(std::vector<CefString>& names) =0;


This is not true, it does not return the main frame.

EDIT 6. Found an another solution to the OnBrowserDestroyed() problem. Doing a javascript
navigation by executing "location='http://...'" instead of the LoadURL(), does not causes
the OnBrowserDestroyed() callback to be fired.

Using CEF 3 branch 1453 revision 1352 on Ubuntu 12.04 64-bit.

Best regards,
Czarek
Last edited by Czarek on Sat Sep 21, 2013 3:35 pm, edited 2 times in total.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: OnBrowserDestroyed() is called when after Frame.LoadURL(

Postby magreenblatt » Sat Sep 21, 2013 4:07 am

1. Navigation can cause creation of new render processes if the origin (scheme + domain) changes. Perhaps the google.com URLs are performing a redirect to a different origin or something similar.

2. Where are you calling GetFrameIdentifiers? The browser process only knows about frames that have started to navigate in the render process.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: OnBrowserDestroyed() is called when after Frame.LoadURL(

Postby Czarek » Sat Sep 21, 2013 4:43 am

magreenblatt wrote:2. Where are you calling GetFrameIdentifiers? The browser process only knows about frames that have started to navigate in the render process.

GetFrameIdentifiers() is called in the Renderer process.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: OnBrowserDestroyed() is called when after Frame.LoadURL(

Postby magreenblatt » Sat Sep 21, 2013 8:27 am

Czarek wrote:
magreenblatt wrote:2. Where are you calling GetFrameIdentifiers? The browser process only knows about frames that have started to navigate in the render process.

GetFrameIdentifiers() is called in the Renderer process.

Where in the render process?
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: OnBrowserDestroyed() is called when after Frame.LoadURL(

Postby Czarek » Sat Sep 21, 2013 9:39 am

magreenblatt wrote:Where in the render process?

In the OnProcessMessageReceived() callback.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: OnBrowserDestroyed() is called when after Frame.LoadURL(

Postby Czarek » Sat Sep 21, 2013 9:44 am

magreenblatt wrote:1. Navigation can cause creation of new render processes if the origin (scheme + domain) changes. Perhaps the google.com URLs are performing a redirect to a different origin or something similar.

Why is OnBrowserDestroyed() callecd only when using Frame.LoadURL()? When following a link to load
the same url, or using js "window.location" to redirect to a new url, then OnBrowserDestroyed() is not
being called. Does that make sense? It is exactly the same url in all cases.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: OnBrowserDestroyed() called after Frame.LoadURL()

Postby magreenblatt » Sat Sep 21, 2013 3:47 pm

LoadURL comes from the browser process. Link clicks and document.location come from the render process. The browser generally does not create a new render process for render-initiated navigations. Probably it doesn't need to create a new render process for the LoadURL case either -- it might be interesting to debug why that's happening.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: OnBrowserDestroyed() called after Frame.LoadURL()

Postby perlun » Wed Oct 30, 2013 3:38 pm

I've actually seen similar cases, where OnBrowserDestroyed() isn't being called when you would have expected it to be... It even seems to not always be called even though the render process is destroyed and a new one is started up. Don't really know why, but it's a bit weird.
perlun
Techie
 
Posts: 23
Joined: Tue Jul 23, 2013 11:30 am

Re: OnBrowserDestroyed() called after Frame.LoadURL()

Postby Czarek » Wed Jul 30, 2014 10:36 am

I've finally fixed the issues with Frame.LoadURL. When doing a redirect to a different origin (from "data:text/html," to "file://" in my case) it caused random crashes in V8 bindings. The context provided in CefV8ContextHandler::OnContextCreated may not be valid. It happens randomly, like 70% of time it is valid. Is it a timing issue? Or does Chromium randomly decide whether to create a new renderer process when origin changes? My solution was to abort doing V8 bindings in OnContextCreated when the context is invalid. I have a back-up plan, the bindings are initiated twice. The first time in OnContextCreated in the Renderer process. The second time the bindings are initiated from the Browser process using process messaging. That way V8 bindings always work reliably.

I don't know whether this is a bug, but when CefV8Context::InContext returns false, I can still retrieve contexts using CefV8Context::GetCurrentContext and GetEnteredContext, they return non-NULL values (CefV8Context::GetCurrentContext().get() != NULL). But when you try to call IsValid on them it results in crashes. Looks like invalid pointers are returned.

Testings were made on branch 1650.

On a side note, the solution provided in first post to use ExecuteJavascript "window.location" instead of Frame.LoadURL, does not work for all cases. When trying to do a redirect from "data:text/html" to "file://" it results in javascript error "Cannot load local resource". There seem to be no options in CEF that could allow such origin change. In CefBrowserSettings there are only settings that allow access from file:// urls: "file_access_from_file_urls_allowed" and "universal_access_from_file_urls_allowed".
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: OnBrowserDestroyed() called after Frame.LoadURL()

Postby magreenblatt » Tue Aug 05, 2014 4:44 am

Czarek wrote:When trying to do a redirect from "data:text/html" to "file://" it results in javascript error "Cannot load local resource". There seem to be no options in CEF that could allow such origin change.

This type of origin change will never occur in Chrome so it's possible that there are bugs related to it. It's better to host content from a standard scheme instead of using file://.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 99 guests