Crash in CefBrowser::GetMainFrame

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 in CefBrowser::GetMainFrame

Postby sdiverdi » Wed Sep 08, 2021 1:09 pm

I recently upgraded from build 4324 to 4606 (osx 10.15.7, xcode 12.4). I'm now experiencing frequent crashes in CefBrowser::GetMainFrame. cef_browser.h does not indicate that GetMainFrame can only be called from certain threads (I'm calling it from the browser process). The specific crash is inside NotificationStateLock, a CHECK fail at browser_info.cc:457. I did find this previous forum thread about this issue: viewtopic.php?f=6&t=18564 The suggestion in that thread was to make sure GetMainFrame isn't being called during loading. I have confirmed that is not the case here. My crashing thread looks like this:

Code: Select all
Thread 33 Crashed:
0   org.cef.framework                0x000000010946dcee CefBrowserInfo::NotificationStateLock::NotificationStateLock(CefBrowserInfo*) + 254 (browser_info.cc:457)
1   org.cef.framework                0x000000010946d19d CefBrowserInfo::GetMainFrame() + 61 (browser_info.cc:212)
2   org.cef.framework                0x0000000105c7a6ee (anonymous namespace)::browser_get_main_frame(_cef_browser_t*) + 62 (browser_cpptoc.cc:253)
3   XXXXXXXXXXXXXXX              0x0000000105b5042d CefBrowserCToCpp::GetMainFrame() + 45 (browser_ctocpp.cc:252)

Meanwhile the main thread is also calling GetMainFrame:

Code: Select all
Thread 0:: CrBrowserMain  Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib           0x00007fff70953062 __psynch_mutexwait + 10
1   libsystem_pthread.dylib          0x00007fff70a11917 _pthread_mutex_firstfit_lock_wait + 83
2   libsystem_pthread.dylib          0x00007fff70a0f937 _pthread_mutex_firstfit_lock_slow + 222
3   org.cef.framework                0x00000001098499c6 base::internal::LockImpl::LockInternalWithTracking() + 70 (lock_impl_posix.cc:86)
4   org.cef.framework                0x000000010946df7b CefBrowserInfo::NotificationStateLock::~NotificationStateLock() + 651 (browser_info.cc:472)
5   org.cef.framework                0x000000010946d1c8 CefBrowserInfo::GetMainFrame() + 104 (browser_info.cc:217)
6   org.cef.framework                0x0000000105c7a6ee (anonymous namespace)::browser_get_main_frame(_cef_browser_t*) + 62 (browser_cpptoc.cc:253)
7   XXXXXXXXXXXXXXX              0x0000000105b5042d CefBrowserCToCpp::GetMainFrame() + 45 (browser_ctocpp.cc:252)

So a few questions: Should it be okay to call GetMainFrame from threads other than the UI thread? Should it be thread-safe (so it can be called from multiple threads without synchronization)? I would expect from what I know of the docs that both those answers are yes and this is a bug...
sdiverdi
Mentor
 
Posts: 51
Joined: Fri Dec 25, 2020 7:41 pm

Re: Crash in CefBrowser::GetMainFrame

Postby magreenblatt » Wed Sep 08, 2021 1:41 pm

Both of those call stacks appear to be your client code calling GetMainFrame. Where are you calling it from?
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Crash in CefBrowser::GetMainFrame

Postby sdiverdi » Wed Sep 08, 2021 1:58 pm

Correct. I don't understand what type of answer you're seeking, but I'll try. Both calls are in the browser process. On the main thread, I receive a stream of events from an independent (asynchronous) library that I then pass on to the renderer process like this:

Code: Select all
browser->GetMainFrame()->SendProcessMessage(PID_RENDERER, msg);

The other call is on a separate thread I'm using for another library that also generates an independent, asynchronous event stream, which I then pass to the javascript environment of my HTML page being rendered by CEF, like this:

Code: Select all
browser->GetMainFrame()->ExecuteJavaScript(code, "", 0);

I've written the code this way because the documentation suggested (and my previous work with build 4324 supported) that I could call GetMainFrame, ExecuteJavaScript, and SendProcessMessage in a threadsafe manner. Are there specific rules about when/where these functions are allowed to be called?
sdiverdi
Mentor
 
Posts: 51
Joined: Fri Dec 25, 2020 7:41 pm

Re: Crash in CefBrowser::GetMainFrame

Postby magreenblatt » Wed Sep 08, 2021 2:39 pm

Just to be clear, there are no other CEF callbacks in the call stacks that lead to the problematic GetMainFrame calls?

Note that you can likely avoid the crash by moving both GetMainFrame uses to the same thread.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Crash in CefBrowser::GetMainFrame

Postby sdiverdi » Wed Sep 08, 2021 3:19 pm

Hmm. Here's the full trace of the two threads, with internal names x'ed out. The main thread:

Code: Select all
Thread 0:: CrBrowserMain  Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib           0x00007fff70953062 __psynch_mutexwait + 10
1   libsystem_pthread.dylib          0x00007fff70a11917 _pthread_mutex_firstfit_lock_wait + 83
2   libsystem_pthread.dylib          0x00007fff70a0f937 _pthread_mutex_firstfit_lock_slow + 222
3   org.cef.framework                0x00000001098499c6 base::internal::LockImpl::LockInternalWithTracking() + 70 (lock_impl_posix.cc:86)
4   org.cef.framework                0x000000010946df7b CefBrowserInfo::NotificationStateLock::~NotificationStateLock() + 651 (browser_info.cc:472)
5   org.cef.framework                0x000000010946d1c8 CefBrowserInfo::GetMainFrame() + 104 (browser_info.cc:217)
6   org.cef.framework                0x0000000105c7a6ee (anonymous namespace)::browser_get_main_frame(_cef_browser_t*) + 62 (browser_cpptoc.cc:253)
7   XXXXXXXXXXXXXXXXX              0x0000000105b5042d CefBrowserCToCpp::GetMainFrame() + 45 (browser_ctocpp.cc:252)
8   XXXXXXXXXXXXXXXXX             0x0000000105b0ca99 XXXXXXXXXXXXXXXXX (XXXXXXXXXXXXXXXXX)
9   libdispatch.dylib                0x00007fff707b56c4 _dispatch_call_block_and_release + 12
10  libdispatch.dylib                0x00007fff707b6658 _dispatch_client_callout + 8
11  libdispatch.dylib                0x00007fff707c1cab _dispatch_main_queue_callback_4CF + 936
12  com.apple.CoreFoundation         0x00007fff3678e911 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
13  com.apple.CoreFoundation         0x00007fff3674e717 __CFRunLoopRun + 2028
14  com.apple.CoreFoundation         0x00007fff3674d8ce CFRunLoopRunSpecific + 462
15  com.apple.HIToolbox              0x00007fff35379abd RunCurrentEventLoopInMode + 292
16  com.apple.HIToolbox              0x00007fff353797d5 ReceiveNextEventCommon + 584
17  com.apple.HIToolbox              0x00007fff35379579 _BlockUntilNextEventMatchingListInModeWithFilter + 64
18  com.apple.AppKit                 0x00007fff339c0739 _DPSNextEvent + 883
19  com.apple.AppKit                 0x00007fff339bef80 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
20  com.apple.AppKit                 0x00007fff339b0c8e -[NSApplication run] + 658
21  org.cef.framework                0x0000000109853c3c base::MessagePumpNSApplication::DoRun(base::MessagePump::Delegate*) + 300
22  org.cef.framework                0x0000000109852a53 base::MessagePumpCFRunLoopBase::Run(base::MessagePump::Delegate*) + 131 (message_pump_mac.mm:160)
23  org.cef.framework                0x00000001098102c0 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta) + 208 (thread_controller_with_message_pump_impl.cc:470)
24  org.cef.framework                0x00000001097da42b base::RunLoop::Run(base::Location const&) + 411 (run_loop.cc:136)
25  org.cef.framework                0x00000001094a0ecb CefMainRunner::RunMessageLoop() + 139 (main_runner.cc:288)
26  XXXXXXXXXXXXXXXXX              0x0000000105b2174e main + 1598 (XXXXXXXXXXXXXXXXX)
27  libdyld.dylib                    0x00007fff7080fcc9 start + 1

and the crashing thread:

Code: Select all
Thread 33 Crashed:
0   org.cef.framework                0x000000010946dcee CefBrowserInfo::NotificationStateLock::NotificationStateLock(CefBrowserInfo*) + 254 (browser_info.cc:457)
1   org.cef.framework                0x000000010946d19d CefBrowserInfo::GetMainFrame() + 61 (browser_info.cc:212)
2   org.cef.framework                0x0000000105c7a6ee (anonymous namespace)::browser_get_main_frame(_cef_browser_t*) + 62 (browser_cpptoc.cc:253)
3   XXXXXXXXXXXXXXXXX             0x0000000105b5042d CefBrowserCToCpp::GetMainFrame() + 45 (browser_ctocpp.cc:252)
4   XXXXXXXXXXXXXXXXX             0x0000000105b2d494 XXXXXXXXXXXXXXXXX + 84 (XXXXXXXXXXXXXXXXX
5   XXXXXXXXXXXXXXXXX            0x000000016336da82 XXXXXXXXXXXXXXXXX + 586 (XXXXXXXXXXXXXXXXX)
6   XXXXXXXXXXXXXXXXX            0x000000016336bed9 XXXXXXXXXXXXXXXXX + 327 (XXXXXXXXXXXXXXXXX)
7   XXXXXXXXXXXXXXXXX           0x000000016336bc1e XXXXXXXXXXXXXXXXX + 76 (XXXXXXXXXXXXXXXXX)
8   XXXXXXXXXXXXXXXXX           0x000000016348c028 0x1633c9000 + 798760
9   XXXXXXXXXXXXXXXXX           0x000000016356ebc5 0x1633c9000 + 1727429
10  XXXXXXXXXXXXXXXXX           0x000000016356e4ba 0x1633c9000 + 1725626
11  XXXXXXXXXXXXXXXXX           0x000000016356e835 0x1633c9000 + 1726517
12  XXXXXXXXXXXXXXXXX           0x00000001635366fc 0x1633c9000 + 1496828
13  XXXXXXXXXXXXXXXXX           0x000000016354c798 0x1633c9000 + 1587096
14  XXXXXXXXXXXXXXXXX           0x000000016362b9d6 0x1633c9000 + 2501078
15  XXXXXXXXXXXXXXXXX           0x000000016362b969 0x1633c9000 + 2500969
16  XXXXXXXXXXXXXXXXX           0x000000016362d86b 0x1633c9000 + 2508907
17  XXXXXXXXXXXXXXXXX           0x000000016362bb23 0x1633c9000 + 2501411
18  XXXXXXXXXXXXXXXXX           0x000000016362efb8 0x1633c9000 + 2514872
19  libsystem_pthread.dylib          0x00007fff70a14109 _pthread_start + 148
20  libsystem_pthread.dylib          0x00007fff70a0fb8b thread_start + 15


Agreed that will probably fix this (moving both calls to the same thread), or even adding my own synchronization to these calls. Still, seems like a bug in the current release? If not, and there's some documentation I'm missing (or mis-interpreting) that indicates when/where these calls are allowed I'd really like to see that so I can design my architecture to avoid other similar errors in the future. Thanks as always!
sdiverdi
Mentor
 
Posts: 51
Joined: Fri Dec 25, 2020 7:41 pm

Re: Crash in CefBrowser::GetMainFrame

Postby magreenblatt » Thu Sep 09, 2021 4:14 am

Thanks for the details. I agree that it’s probably a bug. Please add an issue.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Crash in CefBrowser::GetMainFrame

Postby amaitland » Thu Sep 09, 2021 4:57 am

For what it's worth here's another stack trace for NotificationStateLock crash from GetMainFrame

Code: Select all
        libcef.dll!CefBrowserInfo::NotificationStateLock::NotificationStateLock(CefBrowserInfo * browser_info) Line 568   C++
    libcef.dll!CefBrowserInfo::GetMainFrame() Line 230   C++
    libcef.dll!CefBrowserHostBase::GetFrame(__int64 identifier) Line 637   C++
    libcef.dll!CefBrowserHostBase::GetMainFrame() Line 626   C++
    libcef.dll!`anonymous namespace'::browser_get_main_frame(_cef_browser_t * self) Line 253   C++
   CefSharp.Core.Runtime.dll!CefBrowserCToCpp::GetMainFrame(void)   Unknown
    [Managed to Native Transition]   
    [Frames below may be incorrect and/or missing]   
    [Frames below may be incorrect and/or missing]   
    [Frames below may be incorrect and/or missing, no binaries loaded for mylibrary.dll]   
    [Frames below may be incorrect and/or missing]   
    [Native to Managed Transition]   
    CefSharp.Core.Runtime.dll!CefCToCppRefCounted<class CefRequestCallbackCToCpp,class CefRequestCallback,struct _cef_request_callback_t>::Wrap(struct _cef_request_callback_t *)   Unknown
    libcef.dll!CefResourceRequestHandlerCToCpp::OnResourceLoadComplete(scoped_refptr<CefBrowser> browser={...}, scoped_refptr<CefFrame> frame={...}, scoped_refptr<CefRequest> request={...}, scoped_refptr<CefResponse> response={...}, <unnamed-tag> status=UR_SUCCESS, __int64 received_content_length=748) Line 233   C++
    libcef.dll!net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::CallHandlerOnComplete(net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::RequestState * state, const network::URLLoaderCompletionStatus & status) Line 1023   C++
    libcef.dll!net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::OnRequestComplete(int request_id=73275, const network::ResourceRequest & request, const network::URLLoaderCompletionStatus & status) Line 981   C++
    libcef.dll!net_service::InterceptedRequest::OnDestroy() Line 1051   C++
    [Inline Frame] libcef.dll!base::OnceCallback<void (unsigned int, const std::__1::string &)>::Run(unsigned int args, const std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>> & args) Line 98   C++
    libcef.dll!mojo::InterfaceEndpointClient::NotifyError(const absl::optional<mojo::DisconnectReason> & reason) Line 687   C++
    libcef.dll!mojo::internal::MultiplexRouter::ProcessNotifyErrorTask(mojo::internal::MultiplexRouter::Task * task, mojo::internal::MultiplexRouter::ClientCallBehavior client_call_behavior, base::SequencedTaskRunner * current_task_runner) Line 997   C++
    libcef.dll!mojo::internal::MultiplexRouter::ProcessTasks(mojo::internal::MultiplexRouter::ClientCallBehavior client_call_behavior=ALLOW_DIRECT_CLIENT_CALLS, base::SequencedTaskRunner * current_task_runner=0x00000462002613e0) Line 908   C++
    libcef.dll!mojo::internal::MultiplexRouter::OnPipeConnectionError(bool force_async_dispatch) Line 820   C++
    [Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 98   C++
    libcef.dll!mojo::Connector::HandleError(bool force_pipe_reset, bool force_async_handler) Line 665   C++
    [Inline Frame] libcef.dll!base::RepeatingCallback<void (unsigned int, const mojo::HandleSignalsState &)>::Run(unsigned int args=9, const mojo::HandleSignalsState & args={...}) Line 166   C++
    libcef.dll!mojo::SimpleWatcher::OnHandleReady(int watch_id, unsigned int result=9, const mojo::HandleSignalsState & state={...}) Line 279   C++
    libcef.dll!mojo::SimpleWatcher::Context::Notify(unsigned int result=9, MojoHandleSignalsState signals_state, unsigned int flags) Line 94   C++
    libcef.dll!mojo::SimpleWatcher::Context::CallNotify(const MojoTrapEvent * event=0x0000000a25efed70) Line 63   C++
    libcef.dll!mojo::core::WatcherDispatcher::InvokeWatchCallback(unsigned __int64 context, unsigned int result=9, const mojo::core::HandleSignalsState & state, unsigned int flags=0) Line 95   C++
    libcef.dll!mojo::core::Watch::InvokeCallback(unsigned int result=9, const mojo::core::HandleSignalsState & state={...}, unsigned int flags=0) Line 79   C++
    libcef.dll!mojo::core::RequestContext::~RequestContext() Line 73   C++
    libcef.dll!mojo::core::NodeChannel::OnChannelMessage(const void * payload, unsigned __int64 payload_size, std::__1::vector<mojo::PlatformHandle,std::__1::allocator<mojo::PlatformHandle>> handles) Line 828   C++
    libcef.dll!mojo::core::Channel::TryDispatchMessage(base::span<const char,18446744073709551615> buffer, unsigned __int64 * size_hint=0x0000000a25eff5a0) Line 926   C++
    libcef.dll!mojo::core::Channel::OnReadComplete(unsigned __int64 bytes_read, unsigned __int64 * next_read_size_hint=0x0000000a25eff5a0) Line 826   C++
    [Inline Frame] libcef.dll!mojo::core::`anonymous namespace'::ChannelWin::OnReadDone(unsigned __int64 bytes_read) Line 296   C++
    libcef.dll!mojo::core::`anonymous namespace'::ChannelWin::OnIOCompleted(base::MessagePumpForIO::IOContext * context, unsigned long bytes_transfered=56, unsigned long error) Line 282   C++
    libcef.dll!base::MessagePumpForIO::WaitForIOCompletion(unsigned long timeout) Line 797   C++
    libcef.dll!base::MessagePumpForIO::WaitForWork(base::MessagePump::Delegate::NextWorkInfo next_work_info) Line 770   C++
    libcef.dll!base::MessagePumpForIO::DoRunLoop() Line 752   C++
    libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 80   C++
    libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 471   C++
    libcef.dll!base::RunLoop::Run(const base::Location & location) Line 136   C++
    libcef.dll!base::Thread::Run(base::RunLoop * run_loop) Line 325   C++
    libcef.dll!content::BrowserProcessIOThread::IOThreadRun(base::RunLoop * run_loop=0x0000000a25effa70) Line 128   C++
    libcef.dll!base::Thread::ThreadMain() Line 399   C++
    libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params=0x0000046200270690) Line 113   C++
    kernel32.dll!BaseThreadInitThunk()   Unknown
    ntdll.dll!RtlUserThreadStart()   Unknown


For reference https://github.com/cefsharp/CefSharp/discussions/3786
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1290
Joined: Wed Jan 14, 2015 2:35 am

Re: Crash in CefBrowser::GetMainFrame

Postby magreenblatt » Thu Sep 16, 2021 12:10 pm

magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Crash in CefBrowser::GetMainFrame

Postby amaitland » Thu Sep 16, 2021 7:43 pm

Thank you.
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1290
Joined: Wed Jan 14, 2015 2:35 am


Return to Support Forum

Who is online

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