Object reference incorrectly held at CefShutdown

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.

Object reference incorrectly held at CefShutdown

Postby pascalkhoury » Fri Jun 03, 2022 5:32 am

Hello,

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
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Object reference incorrectly held at CefShutdown

Postby magreenblatt » Fri Jun 03, 2022 6:14 am

What OS and CEF version? Are you using windowed or off-screen browsers? How are you running the CEF message loop?
magreenblatt
Site Admin
 
Posts: 12407
Joined: Fri May 29, 2009 6:57 pm

Re: Object reference incorrectly held at CefShutdown

Postby pascalkhoury » Fri Jun 03, 2022 7:05 am

Windwos 10 Cef 99.0.4844.51 and multithreaded message loop and windowed browser
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Object reference incorrectly held at CefShutdown

Postby magreenblatt » Fri Jun 03, 2022 7:32 am

From your callstack it appears that lmshq::DataModelVC::D2DFDispCef::CBrowserHandler::DoClose is being called after CefShutdown. Can you verify that you got a previous call to OnBeforeClose for that particular browser?
magreenblatt
Site Admin
 
Posts: 12407
Joined: Fri May 29, 2009 6:57 pm

Re: Object reference incorrectly held at CefShutdown

Postby pascalkhoury » Fri Jun 03, 2022 10:15 am

I don't think DoClose is being called after CefShutdown. In my logging I see that DoClose is called and then CefShutdown is called afterafterwards. Also in the DoClose I check that the browser exists only once in the container that stores that browsers and then I delete it.
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Object reference incorrectly held at CefShutdown

Postby pascalkhoury » Wed Jun 08, 2022 2:05 am

In the previous callstacks I always had a popup browser open.

Now I managed to reproduce the assert with only 1 normal browser open but the callstack is different.

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!CefBrowserCppToC::~CefBrowserCppToC() Line 423
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\browser_cpptoc.cc(423)
libcef.dll!CefBrowserCppToC::~CefBrowserCppToC() Line 422
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\browser_cpptoc.cc(422)
libcef.dll!CefCppToCRefCounted<CefBrowserCppToC,CefBrowser,_cef_browser_t>::Release() Line 86
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\cpptoc\cpptoc_ref_counted.h(86)
libcef.dll!CefCppToCRefCounted<CefBrowserCppToC,CefBrowser,_cef_browser_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)
LmsHq_DataModelVC_D2DFDispCef_v1.dll!CefCToCppRefCounted<CefBrowserCToCpp,CefBrowser,_cef_browser_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)
LmsHq_DataModelVC_D2DFDispCef_v1.dll!CefCToCppRefCounted<CefBrowserCToCpp,CefBrowser,_cef_browser_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)
LmsHq_DataModelVC_D2DFDispCef_v1.dll!scoped_refptr<CefBrowser>::Release(CefBrowser * ptr) Line 356
   at C:\Users\rk0xku\.conan\data\Cef\99.0.4844.51\conan-TestLab\Picasso\package\45b43bcd991ec89baf1eb618b595ca3227a3cf0b\include\include\base\cef_scoped_refptr.h(356)
LmsHq_DataModelVC_D2DFDispCef_v1.dll!scoped_refptr<CefBrowser>::~scoped_refptr<CefBrowser>() Line 258
   at C:\Users\rk0xku\.conan\data\Cef\99.0.4844.51\conan-TestLab\Picasso\package\45b43bcd991ec89baf1eb618b595ca3227a3cf0b\include\include\base\cef_scoped_refptr.h(258)
LmsHq_DataModelVC_D2DFDispCef_v1.dll!LmsHq::DataModelVC::D2DFDispCef::CBrowserHandler::OnBeforeClose(scoped_refptr<CefBrowser> ac_xBrowser) Line 169
   at N:\TestLab\Cada-NT\LmsHq\DataModelVC\D2DFDispCef_v1\Local\Code\BrowserHandler.cpp(169)
LmsHq_DataModelVC_D2DFDispCef_v1.dll!`anonymous namespace'::life_span_handler_on_before_close(_cef_life_span_handler_t * self, _cef_browser_t * browser) Line 207
   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(207)
libcef.dll!CefLifeSpanHandlerCToCpp::OnBeforeClose(scoped_refptr<CefBrowser> browser) Line 162
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef_dll\ctocpp\life_span_handler_ctocpp.cc(162)
libcef.dll!CefBrowserHostBase::OnBeforeClose() Line 799
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\browser_host_base.cc(799)
libcef.dll!AlloyBrowserHostImpl::DestroyBrowser() Line 741
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(741)
libcef.dll!AlloyBrowserHostImpl::CloseContents(content::WebContents * source) Line 1169
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(1169)
libcef.dll!AlloyBrowserHostImpl::CloseBrowser(bool force_close) Line 335
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(335)
libcef.dll!AlloyBrowserHostImpl::WindowDestroyed() Line 721
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(721)
libcef.dll!CefBrowserPlatformDelegateNativeWin::WndProc(HWND__ * hwnd, unsigned int message, unsigned int wParam, long lParam) Line 607
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\native\browser_platform_delegate_native_win.cc(607)
user32.dll!__InternalCallWinProc@20()
user32.dll!UserCallWinProcCheckWow()
user32.dll!DispatchClientMessage()
user32.dll!___fnNCDESTROY@4()
ntdll.dll!_KiUserCallbackDispatcher@12()
LmsHq_DataModelVC_D2DFDispCef_v1.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!AlloyBrowserHostImpl::CloseBrowser(bool force_close) Line 335
   at C:\workdir\cef\chromium-git\chromium\src\cef\libcef\browser\alloy\alloy_browser_host_impl.cc(335)
[Inline Frame] libcef.dll!base::internal::FunctorTraits<void (CefMenuModelImpl::*)(bool) __attribute__((thiscall)),void>::Invoke(void(CefMenuModelImpl::*)(bool) method, scoped_refptr<CefMenuModelImpl> && receiver_ptr, bool && 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(CefMenuModelImpl::*)(bool) && functor, scoped_refptr<CefMenuModelImpl> && args, bool && 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 (CefMenuModelImpl::*)(bool) __attribute__((thiscall)),scoped_refptr<CefMenuModelImpl>,bool>,void ()>::RunImpl(void(CefMenuModelImpl::*)(bool) && functor, std::__1::tuple<scoped_refptr<CefMenuModelImpl>,bool> && 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 (CefMenuModelImpl::*)(bool) __attribute__((thiscall)),scoped_refptr<CefMenuModelImpl>,bool>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 745
   at C:\workdir\cef\chromium-git\chromium\src\base\bind_internal.h(745)
[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()
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Object reference incorrectly held at CefShutdown

Postby pascalkhoury » Wed Jun 08, 2022 3:07 am

This is some logging that shows the succession of events and also some sample code that shows what I am doing at shutdown
Code: Select all
CBrowserHandler::OnAfterCreated browser 1
Application is shutting down. Close all open browsers
CBrowserHandler::DoClose browser 1
CBrowserHandler::OnBeforeClose browser 1
CBrowserManager::OnBeforeClose: All browsers closed
Calling CefShutdown
[0608/093752.603:FATAL:shutdown_checker.cc(30)] Check failed: !IsCefShutdown(). Object reference incorrectly held at CefShutdown


Code: Select all
// called on application main thread
void CCefApp::OnPreShutdown()
{
  printf( "Application is shutting down. Close all open browsers\n" );
  CBrowserManager::Instance().CloseAllBrowsers(); // this will wait for all the browsers' OnBeforeClose to be called

  printf("Calling CefShutdown\n");
  CefShutdown();
  printf("CefShutdown done\n");
}

void CBrowserHandler::OnAfterCreated( CefRefPtr< CefBrowser > browser )
{
  CEF_REQUIRE_UI_THREAD();

  printf( "CBrowserHandler::OnAfterCreated browser %d\n", browser->GetIdentifier() );
  CBrowserManager::Instance().OnAfterCreated( browser );
}

void CBrowserHandler::OnBeforeClose( CefRefPtr< CefBrowser > browser )
{
  CEF_REQUIRE_UI_THREAD();

  printf( "CBrowserHandler::OnBeforeClose browser %d\n", browser->GetIdentifier() );
  CBrowserManager::Instance().OnBeforeClose( browser );
}

bool CBrowserHandler::DoClose( CefRefPtr< CefBrowser > browser )
{
  CEF_REQUIRE_UI_THREAD();

  printf( "CBrowserHandler::DoClose browser %d\n", browser->GetIdentifier() );
  if ( browser->GetHost()->IsWindowRenderingDisabled() == true ) return false;
 
  ::DestroyWindow( browser->GetHost()->GetWindowHandle() );

  return true;
}

void CBrowserManager::CloseAllBrowsers()
{
  {
    auto const lock = std::lock_guard( _browsersMutex );
    if ( _browsers.empty() == true ) return;

    _browsersClosedEvent.reset();
    for ( auto const & [ id, browser ] : _browsers )
    {
      browser->GetHost()->CloseBrowser( true );
    }
  }

  // wait for the event to be triggered before calling CefShutdown.
  _browsersClosedEvent.wait();
}

void CBrowserManager::OnAfterCreated( CefRefPtr< CefBrowser > browser )
{
  auto const lock = std::lock_guard( _browsersMutex );
  assert( _browsers.count( browser->GetIdentifier() ) == 0 );
  _browsers[ browser->GetIdentifier() ] = browser;
}

void CBrowserManager::OnBeforeClose( CefRefPtr< CefBrowser > browser )
{
  auto const lock = std::lock_guard( _browsersMutex );
  assert( _browsers.count( browser->GetIdentifier() ) == 1 );
  _browsers.erase( browser->GetIdentifier() );

  if ( _browsers.empty() == true )
  {
    printf( "CBrowserManager::OnBeforeClose: All browsers closed.\n" );
    _browsersClosedEvent.trigger();
    ::Sleep( 300 ); // adding this sleep will guarantee that the AssertNotShutdown is triggered
  }
}
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Object reference incorrectly held at CefShutdown

Postby magreenblatt » Wed Jun 08, 2022 4:41 am

How are you implementing OnBeforePopup? You need to assign a client so that you get callbacks.
magreenblatt
Site Admin
 
Posts: 12407
Joined: Fri May 29, 2009 6:57 pm

Re: Object reference incorrectly held at CefShutdown

Postby pascalkhoury » Wed Jun 08, 2022 5:14 am

I don't override OnBeforePopup so the same client that handles the main browser also handles the popups (I do get callbacks).
pascalkhoury
Techie
 
Posts: 25
Joined: Fri Apr 15, 2022 8:21 am

Re: Object reference incorrectly held at CefShutdown

Postby magreenblatt » Wed Jun 08, 2022 8:36 am

In that case you should get separate OnBeforeClose for the main window and the popup window.
magreenblatt
Site Admin
 
Posts: 12407
Joined: Fri May 29, 2009 6:57 pm

Next

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 46 guests