Crash on exit after updating to rev 2987

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.

Crash on exit after updating to rev 2987

Postby simonpearce » Mon Apr 10, 2017 6:15 pm

My application that uses CefDoMessageLoopWork() (versus CefRunMessageLoop()) crashes on exit after I upgraded to rev 2987 from rev 2526.

This is how I currently handle exit:

* Use requests that app exit
* Code calls CefBrowserHost::CloseBrowser(false)
* When CefLifeSpanHandler::OnBeforeClose(..) gets called, I trigger a flag in the app
* This flag tells the app to exit its Windows message loop
* After the message loop is done, and just before the app exits, I call CefShutdown()

The stack is mostly opaque calls to functions inside libcef.dll but the final entry is :
Code: Select all
> test_exit.exe!scoped_refptr<CefBrowser>::~scoped_refptr<CefBrowser>() Line 328   C++


Did the correct shutdown procedure change or is there something I'm missing in my shutdown sequence?
simonpearce
Techie
 
Posts: 36
Joined: Tue Oct 27, 2015 2:32 pm

Re: Crash on exit after updating to rev 2987

Postby amaitland » Mon Apr 10, 2017 6:55 pm

Try calling ` CefDoMessageLoopWork()` 10 times before calling Shutdown.

Your message queue probably hasn't finished running.
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1292
Joined: Wed Jan 14, 2015 2:35 am

Re: Crash on exit after updating to rev 2987

Postby simonpearce » Mon Apr 10, 2017 7:06 pm

That didn't help I'm afraid - even running it many, many times.
simonpearce
Techie
 
Posts: 36
Joined: Tue Oct 27, 2015 2:32 pm

Re: Crash on exit after updating to rev 2987

Postby amaitland » Mon Apr 10, 2017 8:35 pm

Are you using a Release build? Your releasing all `CefRefPtr` references?
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1292
Joined: Wed Jan 14, 2015 2:35 am

Re: Crash on exit after updating to rev 2987

Postby simonpearce » Tue Apr 11, 2017 10:44 am

It doesn't crash in Release actually - only in Debug.
simonpearce
Techie
 
Posts: 36
Joined: Tue Oct 27, 2015 2:32 pm

Re: Crash on exit after updating to rev 2987

Postby simonpearce » Tue Apr 11, 2017 11:42 am

So I distilled my application down to a 200 line example which still crashes on exit. I expect I've made an obvious mistake - pointers very welcome.

Built against CEF 3.2987.1591.gd3e47f5 Win32

Code: Select all
#include <iostream>
#include <ctime>
#include <list>

#include "cef_app.h"
#include "cef_client.h"
#include "wrapper/cef_helpers.h"

bool gExitFlag = false;

class RenderHandler :
    public CefRenderHandler
{
    public:
        bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect)
        {
            int width = 512;
            int height = 512;
            rect = CefRect(0, 0, width, height);
            return true;
        }

        void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirtyRects, const void* buffer, int width, int height)
        {
            std::cout << "OnPaint() for size: " << width << " x " << height << std::endl;
        }

        IMPLEMENT_REFCOUNTING(RenderHandler);
};

class BrowserClient :
    public CefClient,
    public CefLifeSpanHandler,
    public CefLoadHandler
{
    public:
        BrowserClient(RenderHandler* render_handler) :
            render_handler_(render_handler)
        {
        }

        CefRefPtr<CefRenderHandler> BrowserClient::GetRenderHandler() OVERRIDE
        {
            return render_handler_;
        }

        CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE
        {
            return this;
        }

        void OnLoadingStateChange(CefRefPtr<CefBrowser> browser, bool isLoading, bool canGoBack, bool canGoForward) OVERRIDE
        {
            std::cout << "OnLoadingStateChange: isLoading:" << isLoading << std::endl;
        }

        CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
        {
            return this;
        }

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

            std::cout << "OnAfterCreated: Adding browser from the list" << std::endl;
            browser_list_.push_back(browser);
        }

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

            BrowserList::iterator bit = browser_list_.begin();
            for (; bit != browser_list_.end(); ++bit)
            {
                if ((*bit)->IsSame(browser))
                {
                    std::cout << "OnBeforeClose: Removing browser from the list" << std::endl;
                    browser_list_.erase(bit);
                    break;
                }
            }

            if (browser_list_.empty())
            {
                std::cout << "Browser List is empty - setting Exit flag" << std::endl;
                gExitFlag = true;
            }
        }

        IMPLEMENT_REFCOUNTING(BrowserClient);

    private:
        CefRefPtr<CefRenderHandler> render_handler_;
        typedef std::list<CefRefPtr<CefBrowser>> BrowserList;
        BrowserList browser_list_;
};

class CefMinimal : public CefApp
{
    public:
        bool init()
        {
            CefMainArgs args(GetModuleHandle(NULL));

            CefSettings settings;
            CefString(&settings.browser_subprocess_path) = "cef_minimal_host.exe";

            if (CefInitialize(args, settings, this, NULL))
            {
                std::cout << "CefMinimal initialized okay" << std::endl;

                render_handler_ = new RenderHandler();
                browser_client_ = new BrowserClient(render_handler_);

                CefWindowInfo window_info;
                window_info.windowless_rendering_enabled = true;

                CefBrowserSettings browser_settings;
                browser_settings.windowless_frame_rate = 60;

                CefString url = "http://cnn.com";
                CefRefPtr<CefRequestContext> request_context = NULL;
                browser_ = CefBrowserHost::CreateBrowserSync(window_info, browser_client_.get(), url, browser_settings, request_context);

                return true;
            }

            std::cout << "Unable to initialize" << std::endl;
            return false;
        }

        void update()
        {
            CefDoMessageLoopWork();
        }

        void requestExit()
        {
            if (browser_.get() && browser_->GetHost() && gExitFlag == false)
            {
                std::cout << "Calling CloseBrowser()" << std::endl;
                browser_->GetHost()->CloseBrowser(false);
            }
        }

        void shutdown()
        {
            std::cout << "Calling CefShutdown();" << std::endl;

            CefShutdown();
        }

        IMPLEMENT_REFCOUNTING(CefMinimal);

    private:
        CefRefPtr<RenderHandler> render_handler_;
        CefRefPtr<BrowserClient> browser_client_;
        CefRefPtr<CefBrowser> browser_;
};

int main(int argc, char* argv[])
{
    CefMinimal* cm = new CefMinimal();

    cm->init();

    time_t start_time;
    time(&start_time);

    MSG msg;
    do
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            cm->update();

            if (gExitFlag == false && time(nullptr) > start_time + 3)
            {
                std::cout << "Timer elapsed - requesting exit" << std::endl;
                cm->requestExit();
            }

            if (gExitFlag)
            {
                std::cout << "Exit flag triggered - posting a WM_QUIT message" << std::endl;
                PostQuitMessage(0);
            }
        }
    }
    while (msg.message != WM_QUIT);

    std::cout << "Exited our message loop" << std::endl;

    cm->shutdown();

    return 0;
}
simonpearce
Techie
 
Posts: 36
Joined: Tue Oct 27, 2015 2:32 pm

Re: Crash on exit after updating to rev 2987

Postby Czarek » Tue Apr 11, 2017 12:25 pm

You are not releasing CefRefPtr reference for Browser - "browser_" variable must be released before shutdown.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. My LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1927
Joined: Sun Nov 06, 2011 2:12 am

Re: Crash on exit after updating to rev 2987

Postby simonpearce » Tue Apr 11, 2017 12:42 pm

Do you mean call browser_->Release() just before I call CefShutdown()?

I've tried that (along with similar calls for render_handler_ and browser_client_) but that didn't appear to make a difference.
simonpearce
Techie
 
Posts: 36
Joined: Tue Oct 27, 2015 2:32 pm

Re: Crash on exit after updating to rev 2987

Postby 0xDEADFEED » Mon May 01, 2017 4:26 am

I am also investigating a crash on exit that started after an upgrade to branch 2987 and 3071. Did you ever find the cause of your issue?
0xDEADFEED
Newbie
 
Posts: 6
Joined: Thu Mar 30, 2017 6:00 pm

Re: Crash on exit after updating to rev 2987

Postby simonpearce » Mon May 01, 2017 11:19 am

Not exactly and trying to call Release on any CefRefPtrs didn't work for me - setting them explicitly to NULL seemed to do the and my apps appears to exit cleanly with no warnings or messages in both release and debug configurations.
simonpearce
Techie
 
Posts: 36
Joined: Tue Oct 27, 2015 2:32 pm

Next

Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 95 guests