应用程序退出时CEF崩溃(QT5 + CEF3.2526)

时间:2016-08-02 09:10:35

标签: c++ qt crash chromium-embedded

这是一个非常简单的QT + CEF窗口应用程序,请参阅https://github.com/GreatTux/CefMinGWQt

当我关闭主窗口CEF触发断点时: 我想我在这里失败了:

void CefBrowserMainParts::PostMainMessageLoopRun() {
....
#ifndef NDEBUG
// No CefBrowserContext instances should exist at this point.
DCHECK_EQ(0, CefBrowserContext::DebugObjCt);
#endif
}

我不知道释放浏览器资源的正确方法是什么,我在网上看了很多例子,几乎所有这些都在我的Windows 7 + vs2010环境中遇到了这个问题

我也试过这个但是没有工作

void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  if(m_browser.get())
    m_browser = NULL;

==== trace ===

libcef.dll!base::debug::BreakDebugger()  Line 21    C++
libcef.dll!logging::LogMessage::~LogMessage()  Line 604 C++
libcef.dll!CefBrowserMainParts::PostMainMessageLoopRun()  Line 189  C++
libcef.dll!content::BrowserMainLoop::ShutdownThreadsAndCleanUp()  Line 946 + 0x27 bytes C++
libcef.dll!content::BrowserMainRunnerImpl::Shutdown()  Line 293 C++
libcef.dll!CefMainDelegate::ShutdownBrowser()  Line 659 + 0x1b bytes    C++
libcef.dll!CefContext::FinalizeShutdown()  Line 462 C++
libcef.dll!CefContext::Shutdown()  Line 345 C++
libcef.dll!CefShutdown()  Line 171  C++
libcef.dll!cef_shutdown()  Line 192 C++
qtloop.exe!CefShutdown()  Line 180 + 0x8 bytes  C++
qtloop.exe!main(int argc=1, char * * argv=0x00375b90)  Line 35  C++
qtloop.exe!WinMain(HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ *    __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000)  Line 113 + 0xd bytes C++
qtloop.exe!__tmainCRTStartup()  Line 547 + 0x2c bytes   C
qtloop.exe!WinMainCRTStartup()  Line 371    C

2 个答案:

答案 0 :(得分:2)

  

关闭主窗口时,Qt不会立即破坏它,所以cef浏览器不会释放。此时app.exec()返回,并且运行了CefShowDown()并触发调试检查。

我也遇到了同样的问题。 这是因为当你关闭Cef时,浏览器也没有空闲

  

DCHECK_EQ(0,CefBrowserContext :: DebugObjCt);

我读了这篇文章并阅读了cef close process的源代码 https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_Close.md

我解决了问题,关键是,当你打电话

  

GETHOST() - &GT; CloseBrowser(假)

在cef上嵌入父窗口的closeEvent并忽略第一个closeEvent

然后,如果用户允许关闭,cef将再次发送接近父根窗口。

void CefBrowserHostImpl::PlatformCloseWindow() {
  if (window_info_.window != NULL) {
    HWND frameWnd = GetAncestor(window_info_.window, GA_ROOT);
    PostMessage(frameWnd, WM_CLOSE, 0, 0);
  }
}

当您重新开始第二次关闭时,您需要确保关闭窗口并将窗口立即嵌入。 Cef需要WM_DESTROY事件来释放资源并调用OnBeforeClose。

答案 1 :(得分:0)

您需要关闭钩子窗口操作,并确保先关闭cef浏览器。

标准流程为(摘自cef注释,有一些修改):

//
// 1.  User clicks the window close button which sends a close notification to
//     the application's top-level window.
// 2.  Application's top-level window receives the close notification and:
//     A. Calls CefBrowserHost::CloseBrowser(false).
//     B. Cancels the window close.
// 3.  JavaScript 'onbeforeunload' handler executes and shows the close
//     confirmation dialog (which can be overridden via
//     CefJSDialogHandler::OnBeforeUnloadDialog()).
// 4.  User approves the close.
// 5.  JavaScript 'onunload' handler executes.
// 6.  Application's DoClose() handler is called. Application will:
//     A. Set a flag to indicate that the next close attempt will be allowed.
//     B. Return false.
// 7.  Sends an close notification to the application's top-level window.
// 8.  Application's top-level window receives the close notification and
//     allows the window to close based on the flag from #6B.
// 9.  Application's top-level window is destroyed.
// 10. Application's OnBeforeClose() handler is called and the browser object
//     is destroyed.
// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
//     exist.
///

我已经基于QT + CEF OSR编写了一个名为QCefWidget的项目。 它具有完善的退出逻辑。 你可以参考