CefPostTask crashing in Release builds

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.

CefPostTask crashing in Release builds

Postby Astaroth » Tue Feb 15, 2022 7:42 pm

My Win32 app works fine with earlier CEF versions like CEF 91.1.21, and I believe 92.0.27. I tried to upgrade it to CEF 98.1.16.

Recent builds such as 98.1.16, and I believe 94.4.11, include changes to the callbacks including adding BindOnce and BindRepeating. I'm now getting callback-related crashes when I compile and link for Release mode (but strangely, Debug mode seems to work).

First, I'm getting some kind of error when I try to do this

::CefPostTask(TID_UI, base::BindRepeating(&CMyBrowserManager::BroadcastMessageToRendererProcesses,this, std::string(message)));

The callstack looks like this:

myapp.exe!base::debug::BreakDebuggerAsyncSafe() Line 21 C++
myapp.exe!logging::LogMessage::~LogMessage() Line 886 C++
myapp.exe!logging::LogMessage::~LogMessage() Line 581 C++
myapp.exe!logging::CheckError::~CheckError() Line 107 C++
[Inline Frame] myapp.exe!base::subtle::RefCountedThreadSafeBase::AddRefWithCheckImpl() Line 209 C++
myapp.exe!base::subtle::RefCountedThreadSafeBase::AddRefWithCheck() Line 176 C++
[Inline Frame] myapp.exe!base::RefCountedThreadSafe<base::internal::BindStateBase,base::internal::BindStateBaseRefCountTraits>::AddRefImpl(base::subtle::StartRefCountFromOneTag) Line 425 C++
[Inline Frame] myapp.exe!base::RefCountedThreadSafe<base::internal::BindStateBase,base::internal::BindStateBaseRefCountTraits>::AddRef() Line 401 C++
[Inline Frame] myapp.exe!scoped_refptr<base::internal::BindStateBase>::AddRef(base::internal::BindStateBase * ptr) Line 315 C++
[Inline Frame] myapp.exe!scoped_refptr<base::internal::BindStateBase>::scoped_refptr(base::internal::BindStateBase * p) Line 191 C++
[Inline Frame] myapp.exe!scoped_refptr<base::internal::BindStateBase>::scoped_refptr(const scoped_refptr<base::internal::BindStateBase> & r) Line 196 C++
myapp.exe!base::internal::CallbackBaseCopyable::CallbackBaseCopyable(const base::internal::CallbackBaseCopyable & c) Line 88 C++
[External Code]

The log says: [0215/165254.319:FATAL:ref_counted.h(209)] Check failed: !needs_adopt_ref_. This RefCounted object is created with non-zero reference count. The first reference to such a object has to be made by AdoptRef or MakeRefCounted.

After a few of these, I see an unhandled exception when it tries _struct->execute() in CefTaskCToCpp::Execute(). For some reason the _struct works in Debug mode but not when I compile and link for Release. Nothing appears in the logs:

> libcef.dll!CefTaskCToCpp::Execute() Line 28 C++
[Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 142 C++
libcef.dll!base::TaskAnnotator::RunTaskImpl(base::PendingTask & pending_task) Line 135 C++
[Inline Frame] libcef.dll!base::TaskAnnotator::RunTask(perfetto::StaticString event_name, base::PendingTask & pending_task, base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl::<lambda_0> && args) Line 74 C++
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow * continuation_lazy_now) Line 356 C++
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() Line 267 C++
libcef.dll!base::MessagePumpForUI::DoRunLoop() Line 221 C++
libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 79 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 142 C++
libcef.dll!CefMainRunner::RunMessageLoop() Line 289 C++
libcef.dll!CefContext::RunMessageLoop() Line 370 C++

Incidentally, one CEF change that surprised me, but that I was able to overcome, is that SendProcessMessage() seems to somehow damage the message, so it's impossible to broadcast the message to multiple processes (IIRC that leads to a crash) . Instead, you have to send a Copy():

for (auto pBrowser : m_pBrowsers)
{
auto pFrame = pBrowser->GetMainFrame();
if (pFrame != nullptr)
{
//SendProcessMessage now seems to damage the message object, so Copy()
//has to be used starting around CEF 92.0.5.
pFrame->SendProcessMessage(PID_RENDERER, pMessage->Copy());
}
}
Astaroth
Techie
 
Posts: 35
Joined: Tue Apr 23, 2019 6:23 pm

Re: CefPostTask crashing in Release builds

Postby magreenblatt » Tue Feb 15, 2022 8:20 pm

First, I'm getting some kind of error when I try to do this

::CefPostTask(TID_UI, base::BindRepeating(&CMyBrowserManager::BroadcastMessageToRendererProcesses,this, std::string(message)));

What is “message”? Is “CMyBrowserManager” ref-counted?
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: CefPostTask crashing in Release builds

Postby Astaroth » Tue Feb 15, 2022 11:55 pm

>What is “message”? Is “CMyBrowserManager” ref-counted?

message is a std::string_view. So it's forming a typical std::string with it.

The CMyBrowserManager class has a single instance with a long lifetime in my app. It is reference-counted, but using our own design. I do not use CefRefPtr for it. It does define AddRef and Release member functions, which I was a afraid could trigger the IsRefCounted (I forget the name) template in CEF. Various attempts to disguise what I'm doing or override the template don't seem to help so I'm not sure how to avoid the crash.

Edit: I renamed my AddRef and Release member functions to AddReference and ReleaseReference. So CEF should not see my class as reference-counted. It's still having the AddRefWithCheck() errors and _struct->execute(_struct) crash.
Another thing I tried is casting this to (void*) and using a non-member function for the callback. Same results.
Astaroth
Techie
 
Posts: 35
Joined: Tue Apr 23, 2019 6:23 pm

Re: CefPostTask crashing in Release builds

Postby Astaroth » Wed Feb 16, 2022 9:42 am

I solved my own problems.

The answer was: CefTask

I made a handful of classes derived from CefTask and I pass a CefRefPtr<CMyDerivedCefTask> to CefPostTask or CefPostDelayedTask and everything works.
No template hell, no error messages, and no crashes. BindOnce/BindRepeating seem like a nightmare in comparison.
Astaroth
Techie
 
Posts: 35
Joined: Tue Apr 23, 2019 6:23 pm

Re: CefPostTask crashing in Release builds

Postby magreenblatt » Wed Feb 16, 2022 11:55 am

Using base::Unretained would likely also solve your problem with the Bind call.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: CefPostTask crashing in Release builds

Postby tapineb371 » Wed Oct 25, 2023 11:54 pm

Astaroth wrote:I solved my own problems.

The answer was: CefTask

I made a handful of classes derived from CefTask and I pass a CefRefPtr<CMyDerivedCefTask> to CefPostTask or CefPostDelayedTask and everything works.
No template hell, no error messages, and no crashes. BindOnce/BindRepeating seem like a nightmare in comparison.



Can you elaborate what you did @Astaroth
tapineb371
Techie
 
Posts: 14
Joined: Mon Sep 04, 2023 8:49 pm


Return to Support Forum

Who is online

Users browsing this forum: No registered users and 210 guests