Crash: Check failed: CefCurrentlyOn(TID_UI)

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.

Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby BorjaPascual » Mon Feb 13, 2023 11:29 am

Hi all,

I am in the process of integrating CEF into my company's software and I have this crash on startup: Check failed: CefCurrentlyOn(TID_UI)
It seems to come from CEF_REQUIRE_UI_THREAD. Also, if I remove it, the crash occurs at cef_browser_host_create_browser. I'm afraid I'm clueless about how to handle this. Any tips, please? Thanks in advance
BorjaPascual
Techie
 
Posts: 27
Joined: Mon Jan 30, 2023 11:25 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby ndesktop » Mon Feb 13, 2023 1:28 pm

" the crash occurs at cef_browser_host_create_browser"
The browser is created on UI thread via a create browser helper AFAIK. There are a couple of DCHECKs/NOTREACHED in cef_browser_host_create_browser.

Try to run your app with "--enable-logging --v=1" from a console, the crash callstack should print.
ndesktop
Master
 
Posts: 756
Joined: Thu Dec 03, 2015 10:10 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby BorjaPascual » Tue Feb 14, 2023 5:05 am

I have tried, but I am unable to do this since I am integrating CEF in a very, very big application. I have also tried to load the debug symbols, but they won't load on VS 2019.
BorjaPascual
Techie
 
Posts: 27
Joined: Mon Jan 30, 2023 11:25 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby pascalkhoury » Tue Feb 14, 2023 6:43 am

What are you doing when you get this assert?

From your comments it seems you are trying to create a browser. Are you using CefBrowserHost::CreateBrowserSync?

If yes then this function can only be called on the CEF UI Thread
Code: Select all
///
// Create a new browser using the window parameters specified by |windowInfo|.
// If |request_context| is empty the global request context will be used.
//
// ----> This is the important part <----
// This method can only be called on the browser process UI thread.
//
// The optional |extra_info| parameter provides an opportunity to specify extra information
// specific to the created browser that will be passed to
// CefRenderProcessHandler::OnBrowserCreated() in the render process.
///
/*--cef(optional_param=client,optional_param=url,
        optional_param=request_context,optional_param=extra_info)--*/
static CefRefPtr<CefBrowser> CreateBrowserSync(
    const CefWindowInfo& windowInfo,
    CefRefPtr<CefClient> client,
    const CefString& url,
    const CefBrowserSettings& settings,
    CefRefPtr<CefDictionaryValue> extra_info,
    CefRefPtr<CefRequestContext> request_context);


You can use CefPostTask to run your function on the CEF UI thread
Code: Select all
CefPostTask( TID_UI, base::BindOnce( & YourApp::CreateBrowser, this, windowInfo, client, url, browserSettings, extraInfo, requestContext ) );
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby BorjaPascual » Tue Feb 14, 2023 6:51 am

pascalkhoury wrote:What are you doing when you get this assert?

From your comments it seems you are trying to create a browser. Are you using CefBrowserHost::CreateBrowserSync?

If yes then this function can only be called on the CEF UI Thread
Code: Select all
///
// Create a new browser using the window parameters specified by |windowInfo|.
// If |request_context| is empty the global request context will be used.
//
// ----> This is the important part <----
// This method can only be called on the browser process UI thread.
//
// The optional |extra_info| parameter provides an opportunity to specify extra information
// specific to the created browser that will be passed to
// CefRenderProcessHandler::OnBrowserCreated() in the render process.
///
/*--cef(optional_param=client,optional_param=url,
        optional_param=request_context,optional_param=extra_info)--*/
static CefRefPtr<CefBrowser> CreateBrowserSync(
    const CefWindowInfo& windowInfo,
    CefRefPtr<CefClient> client,
    const CefString& url,
    const CefBrowserSettings& settings,
    CefRefPtr<CefDictionaryValue> extra_info,
    CefRefPtr<CefRequestContext> request_context);


You can use CefPostTask to run your function on the CEF UI thread
Code: Select all
CefPostTask( TID_UI, base::BindOnce( & YourApp::CreateBrowser, this, windowInfo, client, url, browserSettings, extraInfo, requestContext ) );


Hi! The crash happens at CefBrowserHost::CreateBrowser, when I call CefInitialize. Since it seems to work like some sort of black box, I didn't know I could choose to call the browser in a different way. How can it be done?
BorjaPascual
Techie
 
Posts: 27
Joined: Mon Jan 30, 2023 11:25 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby ndesktop » Tue Feb 14, 2023 6:55 am

"The crash happens at CefBrowserHost::CreateBrowser, when I call CefInitialize"
One first calls CefInitialize, and then CreateBrowser. What exactly does mean "when I call" ?
ndesktop
Master
 
Posts: 756
Joined: Thu Dec 03, 2015 10:10 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby pascalkhoury » Tue Feb 14, 2023 7:04 am

BorjaPascual wrote:
Hi! The crash happens at CefBrowserHost::CreateBrowser, when I call CefInitialize. Since it seems to work like some sort of black box, I didn't know I could choose to call the browser in a different way. How can it be done?


Okay I thought you were calling the Sync version. You can check the documentation here https://magpcss.org/ceforum/apidocs/projects/(default)/CefBrowser.html#CreateBrowser(CefWindowInfo&,CefRefPtr%3CCefClient%3E,constCefString&,constCefBrowserSettings&).

The main difference is that Sync version will block and return the created browser, while the other one will not block and you will be able to get the created browser in the CefLifeSpanHandler that you provide if I am not mistaken.

This is the code of CreateBrowser, you see that there is a few checks at the start of the function, so any of those might be triggered in your case. Can you not load the symbols or check if there is some logging to know what exactly is the error in cef_browser_host_create_browser?

Did you call CefInitialize before creating the browser?

Code: Select all
// static
bool CefBrowserHost::CreateBrowser(
    const CefWindowInfo& windowInfo,
    CefRefPtr<CefClient> client,
    const CefString& url,
    const CefBrowserSettings& settings,
    CefRefPtr<CefDictionaryValue> extra_info,
    CefRefPtr<CefRequestContext> request_context) {
  // Verify that the context is in a valid state.
  if (!CONTEXT_STATE_VALID()) {
    NOTREACHED() << "context not valid";
    return false;
  }

  // Verify that the settings structure is a valid size.
  if (settings.size != sizeof(cef_browser_settings_t)) {
    NOTREACHED() << "invalid CefBrowserSettings structure size";
    return false;
  }

  // Verify windowless rendering requirements.
  if (windowInfo.windowless_rendering_enabled &&
      !client->GetRenderHandler().get()) {
    NOTREACHED() << "CefRenderHandler implementation is required";
    return false;
  }

  if (windowInfo.windowless_rendering_enabled &&
      !CefContext::Get()->settings().windowless_rendering_enabled) {
    LOG(ERROR) << "Creating a windowless browser without setting "
                  "CefSettings.windowless_rendering_enabled may result in "
                  "reduced performance or runtime errors.";
  }

  if (!request_context) {
    request_context = CefRequestContext::GetGlobalContext();
  }

  auto helper = std::make_unique<CreateBrowserHelper>(
      windowInfo, client, url, settings, extra_info, request_context);

  auto request_context_impl =
      static_cast<CefRequestContextImpl*>(request_context.get());

  // Wait for the browser context to be initialized before creating the browser.
  request_context_impl->ExecuteWhenBrowserContextInitialized(base::BindOnce(
      [](std::unique_ptr<CreateBrowserHelper> helper) {
        // Always execute asynchronously to avoid potential issues if we're
        // being called synchronously during app initialization.
        CEF_POST_TASK(CEF_UIT, base::BindOnce(&CreateBrowserHelper::Run,
                                              std::move(helper)));
      },
      std::move(helper)));

  return true;
}
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby BorjaPascual » Tue Feb 14, 2023 7:09 am

ndesktop wrote:"The crash happens at CefBrowserHost::CreateBrowser, when I call CefInitialize"
One first calls CefInitialize, and then CreateBrowser. What exactly does mean "when I call" ?


CefBrowserHost::CreateBrowser seems to be called from CefInitialize, because the crash is happening when executing CefInitialize.
Call stack is as follows:

Code: Select all
CefBrowserHost::CreateBrowser(const CefWindowInfo & windowInfo, scoped_refptr<CefClient> client, const CefStringBase<CefStringTraitsUTF16> & url, const CefStructBase<CefBrowserSettingsTraits> & settings, scoped_refptr<CefDictionaryValue> extra_info, scoped_refptr<CefRequestContext> request_context) Line 49
CreateBrowser(scoped_refptr<CefClient> client, const CefStringBase<CefStringTraitsUTF16> & startup_url, const CefStructBase<CefBrowserSettingsTraits> & settings) Line 105
CCefSimpleApp::OnContextInitialized() Line 146
anonymous namespace'::browser_process_handler_on_register_custom_preferences(_cef_browser_process_handler_t * self, cef_preferences_type_t type, _cef_preference_registrar_t * registrar) Line 43
CefInitialize(const CefMainArgs & args, const CefStructBase<CefSettingsTraits> & settings, scoped_refptr<CefApp> application, void * windows_sandbox_info) Line 102
BorjaPascual
Techie
 
Posts: 27
Joined: Mon Jan 30, 2023 11:25 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby pascalkhoury » Tue Feb 14, 2023 7:13 am

BorjaPascual wrote:
ndesktop wrote:"The crash happens at CefBrowserHost::CreateBrowser, when I call CefInitialize"
One first calls CefInitialize, and then CreateBrowser. What exactly does mean "when I call" ?


CefBrowserHost::CreateBrowser seems to be called from CefInitialize, because the crash is happening when executing CefInitialize.
Call stack is as follows:

Code: Select all
CefBrowserHost::CreateBrowser(const CefWindowInfo & windowInfo, scoped_refptr<CefClient> client, const CefStringBase<CefStringTraitsUTF16> & url, const CefStructBase<CefBrowserSettingsTraits> & settings, scoped_refptr<CefDictionaryValue> extra_info, scoped_refptr<CefRequestContext> request_context) Line 49
CreateBrowser(scoped_refptr<CefClient> client, const CefStringBase<CefStringTraitsUTF16> & startup_url, const CefStructBase<CefBrowserSettingsTraits> & settings) Line 105
CCefSimpleApp::OnContextInitialized() Line 146
anonymous namespace'::browser_process_handler_on_register_custom_preferences(_cef_browser_process_handler_t * self, cef_preferences_type_t type, _cef_preference_registrar_t * registrar) Line 43
CefInitialize(const CefMainArgs & args, const CefStructBase<CefSettingsTraits> & settings, scoped_refptr<CefApp> application, void * windows_sandbox_info) Line 102


Are you not the one who is calling CreateBrowser? Can you maybe post a bit more code on how you are initializing and creating the browser?
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Crash: Check failed: CefCurrentlyOn(TID_UI)

Postby BorjaPascual » Tue Feb 14, 2023 7:21 am

pascalkhoury wrote:
BorjaPascual wrote:
ndesktop wrote:"The crash happens at CefBrowserHost::CreateBrowser, when I call CefInitialize"
One first calls CefInitialize, and then CreateBrowser. What exactly does mean "when I call" ?


CefBrowserHost::CreateBrowser seems to be called from CefInitialize, because the crash is happening when executing CefInitialize.
Call stack is as follows:

Code: Select all
CefBrowserHost::CreateBrowser(const CefWindowInfo & windowInfo, scoped_refptr<CefClient> client, const CefStringBase<CefStringTraitsUTF16> & url, const CefStructBase<CefBrowserSettingsTraits> & settings, scoped_refptr<CefDictionaryValue> extra_info, scoped_refptr<CefRequestContext> request_context) Line 49
CreateBrowser(scoped_refptr<CefClient> client, const CefStringBase<CefStringTraitsUTF16> & startup_url, const CefStructBase<CefBrowserSettingsTraits> & settings) Line 105
CCefSimpleApp::OnContextInitialized() Line 146
anonymous namespace'::browser_process_handler_on_register_custom_preferences(_cef_browser_process_handler_t * self, cef_preferences_type_t type, _cef_preference_registrar_t * registrar) Line 43
CefInitialize(const CefMainArgs & args, const CefStructBase<CefSettingsTraits> & settings, scoped_refptr<CefApp> application, void * windows_sandbox_info) Line 102


Are you not the one who is calling CreateBrowser? Can you maybe post a bit more code on how you are initializing and creating the browser?


Yeah, it seems to be CefInitialize. Here's the code, which I copypasted fromm cefsimple:

Code: Select all
CefRefPtr<CefApp> app(new CCefSimpleApp(std::string(url.GetBuffer())));
  int exit_code = CefExecuteProcess(main_args, app, sandbox_info);
  if (exit_code >= 0) {
    // The sub-process has completed so return here.
    return;
  }

  // Parse command-line arguments for use in this method.
  CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
  command_line->InitFromString(::GetCommandLineW());

  // Create the singleton manager instance.
  ClientManager manager;

  // Specify CEF global settings here.
  CefSettings settings;

  if (command_line->HasSwitch("enable-chrome-runtime")) {
    // Enable experimental Chrome runtime. See issue #2969 for details.
    settings.chrome_runtime = true;
  }
 
  // Initialize CEF.
  CefInitialize(main_args, settings, app, sandbox_info);
BorjaPascual
Techie
 
Posts: 27
Joined: Mon Jan 30, 2023 11:25 am

Next

Return to Support Forum

Who is online

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