FATAL error after CefInitialize - MFC Application

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.

FATAL error after CefInitialize - MFC Application

Postby BaroneAshura » Thu May 10, 2018 2:42 am

We have a fairly large application developed in MFC, and we wanted to integrate a small browser window.

We compiled and ran the CefClient and CefSimple applications and made relevant modifications to those solution for testing purposes.
Then we followed the example of this project https://bitbucket.org/TSS_DEV/cef-mfc to understand how to integrate CEF into an MFC application

We managed to compile the dll_wrapper and integrate it into our solution, and as of now, we can see html and run javascript code into our application.

Despite being able to run, we get the following error message :
[0510/085853.881:FATAL:thread_restrictions.cc(29)] Check failed: !g_blocking_disallowed.Get().Get(). Function marked as blocking was called from a scope that disallows blocking! If this task is running inside the TaskScheduler, it needs to have MayBlock() in its TaskTraits. Otherwise, consider making this blocking work asynchronous or, as a last resort, you may use ScopedAllowBlocking in a narrow scope.


This occurs when calling CefInitialize, as highlighted by the following call stack in the main application thread:
libcef.dll!media::UserInputMonitor::UserInputMonitor() Line 19 C++
libcef.dll!media::`anonymous namespace'::UserInputMonitorWin::UserInputMonitorWin(const scoped_refptr<base::SingleThreadTaskRunner> & ui_task_runner) Line 227 C++
[Inline Frame] libcef.dll!std::make_unique(const scoped_refptr<base::SingleThreadTaskRunner> & _Args) Line 2585 C++
libcef.dll!media::UserInputMonitor::Create(const scoped_refptr<base::SingleThreadTaskRunner> & io_task_runner, const scoped_refptr<base::SingleThreadTaskRunner> & ui_task_runner) Line 255 C++
libcef.dll!content::BrowserMainLoop::BrowserThreadsStarted() Line 1506 C++
[Inline Frame] libcef.dll!base::RepeatingCallback<int ()>::Run() Line 124 C++
libcef.dll!content::StartupTaskRunner::RunAllTasksNow() Line 45 C++
libcef.dll!content::BrowserMainLoop::CreateStartupTasks() Line 972 C++
libcef.dll!content::BrowserMainRunnerImpl::Initialize(const content::MainFunctionParams & parameters) Line 140 C++
libcef.dll!CefMainDelegate::RunProcess(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & process_type, const content::MainFunctionParams & main_function_params) Line 592 C++
libcef.dll!content::RunNamedProcessTypeMain(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & process_type, const content::MainFunctionParams & main_function_params, content::ContentMainDelegate * delegate) Line 410 C++
libcef.dll!content::ContentMainRunnerImpl::Run() Line 703 C++
libcef.dll!service_manager::MainRun(service_manager::MainParams & params) Line 464 C++
libcef.dll!CefContext::Initialize(const CefMainArgs & settings, const CefStructBase<CefSettingsTraits> &) Line 398 C++
libcef.dll!CefInitialize(const CefMainArgs &) Line 236 C++
libcef.dll!cef_initialize(const _cef_main_args_t * args, const _cef_settings_t * settings, _cef_app_t * application, void * windows_sandbox_info) Line 228 C++
> MyApp-32-DebugU.exe!CefInitialize(const CefMainArgs & args, const CefStructBase<CefSettingsTraits> & settings, scoped_refptr<CefApp> application, void * windows_sandbox_info) Line 220 C++
MyApp-32-DebugU.exe!CMyAppDlg::InitInstance(unsigned int id_icona, bool bControllaAltraIstanza) Line 603 C++
MyApp-32-DebugU.exe!CMyApp::InitInstance() Line 999 C++
MyApp-32-DebugU.exe!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 37 C++
MyApp-32-DebugU.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 26 C++


the call stack in the thread in the thread (named ChromeIOThread) printing the error message is:
> libcef.dll!base::debug::BreakDebugger() Line 21 C++
libcef.dll!logging::LogMessage::~LogMessage() Line 842 C++
libcef.dll!base::AssertBlockingAllowed() Line 35 C++
libcef.dll!base::MakeAbsoluteFilePath(const base::FilePath & input) Line 211 C++
libcef.dll!base::PathService::Get(int key, base::FilePath * result) Line 218 C++
libcef.dll!content::PathProvider(int key, base::FilePath * result) Line 46 C++
libcef.dll!base::PathService::Get(int key, base::FilePath * result) Line 207 C++
libcef.dll!content::ChildProcessHost::GetChildPath(int flags) Line 71 C++
libcef.dll!content::GpuProcessHost::LaunchGpuProcess() Line 1195 C++
libcef.dll!content::GpuProcessHost::Init() Line 761 C++
libcef.dll!content::GpuProcessHost::Get(content::GpuProcessHost::GpuProcessKind kind, bool force_create) Line 486 C++
libcef.dll!content::BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO() Line 117 C++
[Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 95 C++
libcef.dll!base::debug::TaskAnnotator::RunTask(const char * queue_function, base::PendingTask * pending_task) Line 61 C++
libcef.dll!base::internal::IncomingTaskQueue::RunTask(base::PendingTask * pending_task) Line 124 C++
libcef.dll!base::MessageLoop::RunTask(base::PendingTask * pending_task) Line 396 C++
libcef.dll!base::MessageLoop::DeferOrRunPendingTask(base::PendingTask pending_task) Line 407 C++
libcef.dll!base::MessageLoop::DoWork() Line 451 C++
libcef.dll!base::MessagePumpForIO::DoRunLoop() Line 484 C++
libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 58 C++
libcef.dll!base::MessageLoop::Run(bool application_tasks_allowed) Line 348 C++
libcef.dll!base::RunLoop::Run() Line 136 C++
libcef.dll!base::Thread::Run(base::RunLoop * run_loop) Line 255 C++
libcef.dll!content::BrowserThreadImpl::IOThreadRun(base::RunLoop * run_loop) Line 234 C++
libcef.dll!content::BrowserThreadImpl::Run(base::RunLoop * run_loop) Line 260 C++
libcef.dll!base::Thread::ThreadMain() Line 338 C++
libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 94 C++


CefInitiliaze is being called with the following code at application startup:
Code: Select all
    // initialize CEF.
    m_cefApp = new ClientApp();
    //m_cefAppRenderer = new ClientAppRenderer();

    // get arguments
    CefMainArgs main_args(GetModuleHandle(NULL));

    // Execute the secondary process, if any.
    int exit_code = CefExecuteProcess(main_args, m_cefApp.get(), NULL);
    if (exit_code >= 0)
        return exit_code;

    // setup settings
    CString szCEFCache;
    CString szPath;
    INT nLen = GetTempPath(0, NULL) + 1;
    GetTempPath(nLen, szPath.GetBuffer(nLen));

    // save path
    szCEFCache.Format(_T("%scache\0\0"), szPath);

    // set settings
    CefSettings settings;

    settings.multi_threaded_message_loop = FALSE;
    CefString(&settings.cache_path) = szCEFCache;


    void* sandbox_info = NULL;
#if CEF_ENABLE_SANDBOX
    // Manage the life span of the sandbox information object. This is necessary
    // for sandbox support on Windows. See cef_sandbox_win.h for complete details.
    CefScopedSandboxInfo scoped_sandbox;
    sandbox_info = scoped_sandbox.sandbox_info();
#else
    settings.no_sandbox = TRUE;
#endif

    //CEF Initiaized
    m_bCEFInitialized = CefInitialize(main_args, settings, m_cefApp.get(), sandbox_info);


Just to be complete:
- we are using Visual Studio 2017 version 15.7
- we are targeting 32bit systems with the v141_xp Platform Toolset
- we are running the application on a windows 10 machine

Any hints on how to avoid going through such fatal error? We get other runtime, undesired behaviours, but the at the moment we would like to focus on this one.

Thanks in Advance
BaroneAshura
Newbie
 
Posts: 6
Joined: Thu Apr 26, 2018 2:52 am

Re: FATAL error after CefInitialize - MFC Application

Postby magreenblatt » Thu May 10, 2018 3:06 am

What CEF version are you using? Are you running via Visual Studio? If so, make sure all of your paths are absolute. See viewtopic.php?f=6&t=10725&start=0#p17499
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: FATAL error after CefInitialize - MFC Application

Postby ndesktop » Thu May 10, 2018 5:52 am

Code: Select all
szCEFCache.Format(_T("%scache\0\0"), szPath);

I see two problems here:
1. assuming szPath is C:\TEMP, szCEFCache will become "C:\\TEMPcache\\0\\0"
1.1 Why the double null termination?
1.2 Why not using PathCombine or PathAppend from shlwapi?
2. If the path does not exists, setting cache_path to an invalid path will lead to a DCHECK if I remember well.

I suggest using something similar with (error handling omitted):
Code: Select all
WCHAR szTempPath[MAX_PATH] = L"";
GetTempPathW(_countof(szTempPath), szTempPath);

// get an unique item name in temp dir
WCHAR szRelative[MAX_PATH] = L"";
GetTempFileNameW(szTempPath, L"CCD", 0, szRelative);

WCHAR szCacheDir[MAX_PATH] = L"";
PathCombineW(szCacheDir, szTempPath, szRelative); // needs include shlwapi.h and link with shlwapi.lib

// delete temp file created by GetTempFileNameW
DeleteFileW(szRelative);
// create directory with the same name
CreateDIrectoryW(szCacheDir, NULL);  // or SHCreateDirectory(NULL, szCacheDir); - needs include shlobj.h

CefString(&settings.cache_path) = szCEFCache;
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am

Re: FATAL error after CefInitialize - MFC Application

Postby BaroneAshura » Thu May 10, 2018 6:27 am

magreenblatt wrote:What CEF version are you using? Are you running via Visual Studio? If so, make sure all of your paths are absolute. See https://magpcss.org/ceforum/viewtopic.p ... t=0#p17499

Sorry Forgot to list the CEF version : cef_binary_3.3359.1768 ( downloaded from http://opensource.spotify.com/cefbuilds/index.html a couple of weeks ago)

With respect to paths, I checked all the xxx_path parameters in the CefSettings, and except for the cache directory, everything is set to null.
Am I supposed to set them all to some relevant absolute paths?

ndesktop wrote:
Code: Select all
szCEFCache.Format(_T("%scache\0\0"), szPath);

[...]
[/code]


I changed cache directory string initialization as you suggested, ensuring that the directory exists as well.

Unfortunately the error message still appears.

What puzzles me is that, despite the 'FATAL' label in the error message, web pages are displayed correctly (a little bit slow before starting to load content, but they are fine)
BaroneAshura
Newbie
 
Posts: 6
Joined: Thu Apr 26, 2018 2:52 am

Re: FATAL error after CefInitialize - MFC Application

Postby ndesktop » Thu May 10, 2018 8:05 am

Does something appears in the cache directory, or the cache files are stored in the same directory as the executable?
The FATAL error displayed, it might be a DCHECK.
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am

Re: FATAL error after CefInitialize - MFC Application

Postby magreenblatt » Thu May 10, 2018 8:46 am

Look again at the posted forum link. You need to check your Visual Studio configuration.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: FATAL error after CefInitialize - MFC Application

Postby BaroneAshura » Thu May 10, 2018 10:09 am

magreenblatt wrote:Look again at the posted forum link. You need to check your Visual Studio configuration.

Ok!

I managed to understand where I was supposed to look into Visual Studio configuration, and the error message has disappeared! :)

Now the challenge is to set up Visual Studio to work for everyone in the team without having '..' in the Output Directory setting

Thanks for the help!
BaroneAshura
Newbie
 
Posts: 6
Joined: Thu Apr 26, 2018 2:52 am

Re: FATAL error after CefInitialize - MFC Application

Postby ndesktop » Thu May 10, 2018 1:51 pm

A .props file in the root of solution and including it in all vc(x)proj files solves it. Unpleasant, but later you can configure a variable once and all projects will get the update after reopening the solution.
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am


Return to Support Forum

Who is online

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