I am trying to cleanly shutdown CEF, but I get the "Object reference incorrectly held at CefShutdown" assert.
This is the callstack that I get:
- Code: Select all
libcef.dll!logging::LogMessage::~LogMessage() Line 909
at C:\workdir\cef\chromium-git\chromium\src\base\logging.cc(909)
libcef.dll!cef_log(const char * file, int line, int severity, const char * message) Line 335
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\common\base_impl.cc(335)
MyCef.dll!cef::logging::LogMessage::~LogMessage() Line 187
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\base\cef_logging.cc(187)
MyCef.dll!shutdown_checker::AssertNotShutdown() Line 32
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\shutdown_checker.cc(32)
MyCef.dll!CefLifeSpanHandlerCppToC::~CefLifeSpanHandlerCppToC() Line 226
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\cpptoc\life_span_handler_cpptoc.cc(226)
MyCef.dll!CefLifeSpanHandlerCppToC::`scalar deleting destructor'(unsigned int)
MyCef.dll!CefCppToCRefCounted<CefLifeSpanHandlerCppToC,CefLifeSpanHandler,_cef_life_span_handler_t>::Release() Line 87
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\cpptoc\cpptoc_ref_counted.h(87)
MyCef.dll!CefCppToCRefCounted<CefLifeSpanHandlerCppToC,CefLifeSpanHandler,_cef_life_span_handler_t>::struct_release(_cef_base_ref_counted_t * base) Line 167
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\cpptoc\cpptoc_ref_counted.h(167)
[Inline Frame] libcef.dll!CefCToCppRefCounted<CefLifeSpanHandlerCToCpp,CefLifeSpanHandler,_cef_life_span_handler_t>::UnderlyingRelease() Line 78
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\ctocpp\ctocpp_ref_counted.h(78)
libcef.dll!CefCToCppRefCounted<CefLifeSpanHandlerCToCpp,CefLifeSpanHandler,_cef_life_span_handler_t>::Release() Line 154
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\ctocpp\ctocpp_ref_counted.h(154)
[Inline Frame] libcef.dll!scoped_refptr<CefLifeSpanHandler>::Release(CefLifeSpanHandler * ptr) Line 321
at C:\workdir\cef\chromium-git\chromium\src\base\memory\scoped_refptr.h(321)
[Inline Frame] libcef.dll!scoped_refptr<CefLifeSpanHandler>::~scoped_refptr() Line 223
at C:\workdir\cef\chromium-git\chromium\src\base\memory\scoped_refptr.h(223)
libcef.dll!AlloyBrowserHostImpl::CloseContents(content::WebContents * source) Line 1155
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(1155)
libcef.dll!content::WebContentsImpl::Close(content::RenderViewHost * rvh) Line 7200
at C:\workdir\cef\chromium-git\chromium\src\content\browser\web_contents\web_contents_impl.cc(7200)
libcef.dll!content::RenderViewHostImpl::ClosePageIgnoringUnloadEvents() Line 725
at C:\workdir\cef\chromium-git\chromium\src\content\browser\renderer_host\render_view_host_impl.cc(725)
libcef.dll!base::OnceCallback<void ()>::Run() Line 142
at C:\workdir\cef\chromium-git\chromium\src\base\callback.h(142)
libcef.dll!blink::mojom::LocalMainFrame_ClosePage_ForwardToCallback::Accept(mojo::Message * message) Line 17096
at C:\workdir\cef\chromium-git\chromium\src\out\Debug_GN_x86\gen\third_party\blink\public\mojom\frame\frame.mojom.cc(17096)
libcef.dll!mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message * message) Line 896
at C:\workdir\cef\chromium-git\chromium\src\mojo\public\cpp\bindings\lib\interface_endpoint_client.cc(896)
libcef.dll!mojo::MessageDispatcher::Accept(mojo::Message * message) Line 43
at C:\workdir\cef\chromium-git\chromium\src\mojo\public\cpp\bindings\lib\message_dispatcher.cc(43)
libcef.dll!mojo::InterfaceEndpointClient::HandleIncomingMessage(mojo::Message * message) Line 658
at C:\workdir\cef\chromium-git\chromium\src\mojo\public\cpp\bindings\lib\interface_endpoint_client.cc(658)
libcef.dll!IPC::`anonymous namespace'::ChannelAssociatedGroupController::AcceptOnEndpointThread(mojo::Message message) Line 1008
at C:\workdir\cef\chromium-git\chromium\src\ipc\ipc_mojo_bootstrap.cc(1008)
libcef.dll!base::internal::FunctorTraits<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),void>::Invoke<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message>(void(mojo::`anonymous namespace'::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) method, scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy> && receiver_ptr, mojo::Message && args) Line 535
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(535)
[Inline Frame] libcef.dll!base::internal::InvokeHelper<0,void>::MakeItSo(void(mojo::`anonymous namespace'::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) && functor, scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy> && args, mojo::Message && args) Line 699
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(699)
[Inline Frame] libcef.dll!base::internal::Invoker<base::internal::BindState<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message>,void ()>::RunImpl(void(mojo::`anonymous namespace'::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) && functor, std::__1::tuple<scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message> && bound, std::__1::integer_sequence<unsigned int,0,1>) Line 772
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(772)
libcef.dll!base::internal::Invoker<base::internal::BindState<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 741
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(741)
[Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 142
at C:\workdir\cef\chromium-git\chromium\src\base\callback.h(142)
libcef.dll!base::TaskAnnotator::RunTaskImpl(base::PendingTask & pending_task) Line 135
at C:\workdir\cef\chromium-git\chromium\src\base\task\common\task_annotator.cc(135)
[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
at C:\workdir\cef\chromium-git\chromium\src\base\task\common\task_annotator.h(74)
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow * continuation_lazy_now) Line 356
at C:\workdir\cef\chromium-git\chromium\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc(356)
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() Line 267
at C:\workdir\cef\chromium-git\chromium\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc(267)
libcef.dll!base::MessagePumpForUI::DoRunLoop() Line 221
at C:\workdir\cef\chromium-git\chromium\src\base\message_loop\message_pump_win.cc(221)
libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 79
at C:\workdir\cef\chromium-git\chromium\src\base\message_loop\message_pump_win.cc(79)
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 471
at C:\workdir\cef\chromium-git\chromium\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc(471)
libcef.dll!base::RunLoop::Run(const base::Location & location) Line 140
at C:\workdir\cef\chromium-git\chromium\src\base\run_loop.cc(140)
libcef.dll!CefMainRunner::RunMessageLoop() Line 289
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\main_runner.cc(289)
libcef.dll!CefUIThread::ThreadMain() Line 185
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\main_runner.cc(185)
libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 114
at C:\workdir\cef\chromium-git\chromium\src\base\threading\platform_thread_win.cc(114)
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8()
When my application wants to exit, I call CloseBrowser(true) on all the existing browsers, and then I wait for their OnBeforeClose to be called. In OnBeforeClose I release the reference I have to the browser. I also wait for all the Clients to be destroyed by calling a function in their destructor.
When all clients and browsers signaled that their closed, I call CefShutdown.
But the problem is that sometimes, the last client is still IN THE PROCESS of being destructed when CefShutdown is called (since I signal that it is destructed in its dtor) and then I get that assert. I can reproduce it this assert all the time if I add a Sleep in the dtor of the Client.
If I ignore the destruction of the clients and only signal that CefShutDown can be called when the last browser has been closed (OnBeforeClose) then I also get the same assert but with a different callstack:
- Code: Select all
libcef.dll!logging::LogMessage::~LogMessage() Line 909
at C:\workdir\cef\chromium-git\chromium\src\base\logging.cc(909)
libcef.dll!logging::LogMessage::~LogMessage() Line 593
at C:\workdir\cef\chromium-git\chromium\src\base\logging.cc(593)
libcef.dll!logging::CheckError::~CheckError() Line 109
at C:\workdir\cef\chromium-git\chromium\src\base\check.cc(109)
libcef.dll!shutdown_checker::AssertNotShutdown() Line 32
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\shutdown_checker.cc(32)
[Inline Frame] libcef.dll!CefBrowserHostCppToC::~CefBrowserHostCppToC() Line 1370
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\browser_host_cpptoc.cc(1370)
libcef.dll!CefBrowserHostCppToC::~CefBrowserHostCppToC() Line 1369
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\browser_host_cpptoc.cc(1369)
libcef.dll!CefCppToCRefCounted<CefBrowserHostCppToC,CefBrowserHost,_cef_browser_host_t>::Release() Line 86
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\cpptoc_ref_counted.h(86)
libcef.dll!CefCppToCRefCounted<CefBrowserHostCppToC,CefBrowserHost,_cef_browser_host_t>::struct_release(_cef_base_ref_counted_t * base) Line 167
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\cpptoc_ref_counted.h(167)
MyCef.dll!CefCToCppRefCounted<CefBrowserHostCToCpp,CefBrowserHost,_cef_browser_host_t>::UnderlyingRelease() Line 78
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\ctocpp\ctocpp_ref_counted.h(78)
MyCef.dll!CefCToCppRefCounted<CefBrowserHostCToCpp,CefBrowserHost,_cef_browser_host_t>::Release() Line 154
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\ctocpp\ctocpp_ref_counted.h(154)
MyCef.dll!scoped_refptr<CefBrowserHost>::Release(CefBrowserHost * ptr) Line 356
at C:\Users\rk0xku\.conan\data\Cef\99.0.4844.51\conan\package\45b43bcd991ec89baf1eb618b595ca3227a3cf0b\include\include\base\cef_scoped_refptr.h(356)
MyCef.dll!scoped_refptr<CefBrowserHost>::~scoped_refptr<CefBrowserHost>() Line 258
at C:\Users\rk0xku\.conan\data\Cef\99.0.4844.51\conan\package\45b43bcd991ec89baf1eb618b595ca3227a3cf0b\include\include\base\cef_scoped_refptr.h(258)
MyCef.dll!LmsHq::DataModelVC::D2DFDispCef::CBrowserHandler::DoClose(scoped_refptr<CefBrowser> ac_xBrowser) Line 195
at N:\TestLab\Cada-NT\LmsHq\DataModelVC\D2DFDispCef_v1\Local\Code\BrowserHandler.cpp(195)
MyCef.dll!`anonymous namespace'::life_span_handler_do_close(_cef_life_span_handler_t * self, _cef_browser_t * browser) Line 184
at D:\Stories\Cef\99.0.4844.51\cef_binary_99.2.9+gf426765+chromium-99.0.4844.51_windows32\libcef_dll\cpptoc\life_span_handler_cpptoc.cc(184)
libcef.dll!CefLifeSpanHandlerCToCpp::DoClose(scoped_refptr<CefBrowser> browser) Line 140
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\ctocpp\life_span_handler_ctocpp.cc(140)
libcef.dll!AlloyBrowserHostImpl::CloseContents(content::WebContents * source) Line 1155
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(1155)
libcef.dll!content::WebContentsImpl::Close(content::RenderViewHost * rvh) Line 7200
at C:\workdir\cef\chromium-git\chromium\src\content\browser\web_contents\web_contents_impl.cc(7200)
libcef.dll!content::RenderViewHostImpl::ClosePageIgnoringUnloadEvents() Line 725
at C:\workdir\cef\chromium-git\chromium\src\content\browser\renderer_host\render_view_host_impl.cc(725)
libcef.dll!base::OnceCallback<void ()>::Run() Line 142
at C:\workdir\cef\chromium-git\chromium\src\base\callback.h(142)
libcef.dll!blink::mojom::LocalMainFrame_ClosePage_ForwardToCallback::Accept(mojo::Message * message) Line 17096
at C:\workdir\cef\chromium-git\chromium\src\out\Debug_GN_x86\gen\third_party\blink\public\mojom\frame\frame.mojom.cc(17096)
libcef.dll!mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message * message) Line 896
at C:\workdir\cef\chromium-git\chromium\src\mojo\public\cpp\bindings\lib\interface_endpoint_client.cc(896)
libcef.dll!mojo::MessageDispatcher::Accept(mojo::Message * message) Line 43
at C:\workdir\cef\chromium-git\chromium\src\mojo\public\cpp\bindings\lib\message_dispatcher.cc(43)
libcef.dll!mojo::InterfaceEndpointClient::HandleIncomingMessage(mojo::Message * message) Line 658
at C:\workdir\cef\chromium-git\chromium\src\mojo\public\cpp\bindings\lib\interface_endpoint_client.cc(658)
libcef.dll!IPC::`anonymous namespace'::ChannelAssociatedGroupController::AcceptOnEndpointThread(mojo::Message message) Line 1008
at C:\workdir\cef\chromium-git\chromium\src\ipc\ipc_mojo_bootstrap.cc(1008)
libcef.dll!base::internal::FunctorTraits<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),void>::Invoke<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message>(void(mojo::`anonymous namespace'::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) method, scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy> && receiver_ptr, mojo::Message && args) Line 535
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(535)
[Inline Frame] libcef.dll!base::internal::InvokeHelper<0,void>::MakeItSo(void(mojo::`anonymous namespace'::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) && functor, scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy> && args, mojo::Message && args) Line 699
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(699)
[Inline Frame] libcef.dll!base::internal::Invoker<base::internal::BindState<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message>,void ()>::RunImpl(void(mojo::`anonymous namespace'::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) && functor, std::__1::tuple<scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message> && bound, std::__1::integer_sequence<unsigned int,0,1>) Line 772
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(772)
libcef.dll!base::internal::Invoker<base::internal::BindState<void (mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy::*)(mojo::Message) __attribute__((thiscall)),scoped_refptr<mojo::(anonymous namespace)::ThreadSafeInterfaceEndpointClientProxy>,mojo::Message>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 741
at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(741)
[Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 142
at C:\workdir\cef\chromium-git\chromium\src\base\callback.h(142)
libcef.dll!base::TaskAnnotator::RunTaskImpl(base::PendingTask & pending_task) Line 135
at C:\workdir\cef\chromium-git\chromium\src\base\task\common\task_annotator.cc(135)
[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
at C:\workdir\cef\chromium-git\chromium\src\base\task\common\task_annotator.h(74)
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow * continuation_lazy_now) Line 356
at C:\workdir\cef\chromium-git\chromium\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc(356)
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() Line 267
at C:\workdir\cef\chromium-git\chromium\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc(267)
libcef.dll!base::MessagePumpForUI::DoRunLoop() Line 221
at C:\workdir\cef\chromium-git\chromium\src\base\message_loop\message_pump_win.cc(221)
libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 79
at C:\workdir\cef\chromium-git\chromium\src\base\message_loop\message_pump_win.cc(79)
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 471
at C:\workdir\cef\chromium-git\chromium\src\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc(471)
libcef.dll!base::RunLoop::Run(const base::Location & location) Line 140
at C:\workdir\cef\chromium-git\chromium\src\base\run_loop.cc(140)
libcef.dll!CefMainRunner::RunMessageLoop() Line 289
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\main_runner.cc(289)
libcef.dll!CefUIThread::ThreadMain() Line 185
at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\main_runner.cc(185)
libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 114
at C:\workdir\cef\chromium-git\chromium\src\base\threading\platform_thread_win.cc(114)
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8()
I don't know how else am I supposed to know when it's safe to call CefShutdown.
I can post sample code if needed.
Thanks