Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CefSharp.WinForms.Example.netcore crashes when popup window #4656

Open
1 task done
gearsns opened this issue Dec 17, 2023 · 5 comments
Open
1 task done

CefSharp.WinForms.Example.netcore crashes when popup window #4656

gearsns opened this issue Dec 17, 2023 · 5 comments
Labels
upstream These issues require fixing in the Chromium Embedded Framework(CEF) or Chromium.

Comments

@gearsns
Copy link

gearsns commented Dec 17, 2023

Is there an existing issue for this?

  • I have searched both open/closed issues, no issue already exists.

CefSharp Version

120.1.80

Operating System

Windows 11

Architecture

x64

.Net Version

.Net 6.0

Implementation

WinForms

Reproduction Steps

  1. Run CefSharp.WinForms.Example.netcore
  2. Show popup window
  3. Close popup window
  4. Repeat 2 - 3.

Expected behavior

Expectations is that it will not crash when you close the popup window

Actual behavior

crash

Regression?

No response

Known Workarounds

Is this due to DoClose in LifeSpanHandler.cs?
Excluding control.Dispose() from InnvokeSyncOnUiThreadIfRequired stops crashing.

Does this problem also occur in the CEF Sample Application

No

Other information

html source

<!DOCTYPE HTML>
<html>
<a href="javascript:popup_open()" id="open">Popup!</a>
<a href="javascript:popup_close()" id="close">Close!</a>
<script>
    const popup_open = () => {
        window.open("index.html?pop=on")
    }
    const popup_close = () => {
        parent.window.close()
    }
    const params = new URLSearchParams(document.location.search)
    if (params.has("pop")) {
        document.getElementById("open").style.display = "none"
        document.title = "Popup!!"
    } else {
        document.getElementById("close").style.display = "none"
        document.title = "Popup Main"
    }
</script>
</html>

edit source code
CefSharp.WinForms\Handler\LifeSpanhandler.cs

                        control.InvokeSyncOnUiThreadIfRequired(new Action(() =>
                        {
                            onPopupDestroyed?.Invoke(control, browser);

                            //control.Dispose(); // Comment out!!
                        }));
                        // Add
                        control.InvokeOnUiThreadIfRequired(new Action(() =>
                        {
                            control.Dispose();
                        }));

CefSharp.WinForms.Example\BrowserTabUserControl.cs

                .OnPopupDestroyed((ctrl, popupBrowser) =>
                {
                    //If we docked  DevTools (hosted it ourselves rather than the default popup)
                    //Used when the BrowserTabUserControl.ShowDevToolsDocked method is called
                    if (popupBrowser.MainFrame.Url.Equals("devtools://devtools/devtools_app.html"))
                    {
                        //Dispose of the parent control we used to host DevTools, this will release the DevTools window handle
                        //and the ILifeSpanHandler.OnBeforeClose() will be call after.
                        ctrl.Dispose();
                    }
                    else
                    {
                        //If browser is disposed or the handle has been released then we don't
                        //need to remove the tab in this example. The user likely used the
                        // File -> Close Tab menu option which also calls BrowserForm.RemoveTab
                        if (!ctrl.IsDisposed && ctrl.IsHandleCreated)
                        {
                            if (ctrl.FindForm() is BrowserForm owner)
                            {
                                owner.RemoveTab(ctrl);
                            }

                            //ctrl.Dispose(); // Comment out!!
                        }
                    }
                })
@amaitland
Copy link
Member

@amaitland amaitland added the upstream These issues require fixing in the Chromium Embedded Framework(CEF) or Chromium. label Dec 22, 2023
@amaitland
Copy link
Member

What is the call stack for the exception?

@gearsns
Copy link
Author

gearsns commented Jan 2, 2024

Since Dispose is called in DoClose, shouldn't it be fixed on the CefSharp side, not on the cef side?

The call stack for the exception is as follows:

 	libcef.dll!AlloyBrowserHostImpl::DestroyBrowser() Line 600	C++
 	libcef.dll!AlloyBrowserHostImpl::CloseContents(content::WebContents * source) Line 1040	C++
 	[Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 154	C++
 	libcef.dll!base::TaskAnnotator::RunTaskImpl(base::PendingTask & pending_task) Line 201	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 89	C++
 	[Inline Frame] libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow * continuation_lazy_now) Line 461	C++
 	libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() Line 326	C++
 	libcef.dll!base::MessagePumpForUI::DoRunLoop() Line 214	C++
 	libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 80	C++
 	libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 629	C++
 	libcef.dll!base::RunLoop::Run(const base::Location & location) Line 136	C++
>	[Inline Frame] libcef.dll!CefMainRunner::RunMessageLoop() Line 312	C++
 	libcef.dll!CefUIThread::ThreadMain() Line 182	C++
 	libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 133	C++
 	kernel32.dll!00007ff81e64257d()	Unknown
 	ntdll.dll!00007ff81feeaa58()	Unknown

@amaitland
Copy link
Member

Since Dispose is called in DoClose, shouldn't it be fixed on the CefSharp side, not on the cef side?

For me that's just hacking around the issue. Calling Dispose (which calls CefBrowserHost::CloseBrowser) works most of the time, there's a threading issue which means it throws some of the time. Even if we move the call in the same code, that won't fix user code.

The LifespanHandler provided is just a default implementation. You can override the behaviour of the default implementation to workaround the issue in your own code.

If the CEF maintainer deems this as won't fix, then we can look at working around the issue.

@amaitland
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
upstream These issues require fixing in the Chromium Embedded Framework(CEF) or Chromium.
Projects
None yet
Development

No branches or pull requests

2 participants