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());
}
}