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

QCefWidget misses CEF main frame after being hidden once #375

Open
StefanEnsmann opened this issue Aug 16, 2022 · 5 comments
Open

QCefWidget misses CEF main frame after being hidden once #375

StefanEnsmann opened this issue Aug 16, 2022 · 5 comments

Comments

@StefanEnsmann
Copy link

Operating System Info

Windows 11

Other OS

No response

OBS Studio Version

28.0.0-beta2

OBS Studio Version (Other)

No response

OBS Studio Log URL

https://obsproject.com/logs/FVEWXEztE0yVkLau

OBS Studio Crash Log URL

None available

Expected Behavior

QCefWidget (nested in a QDialog) can set the URL and be shown properly after being closed.

Current Behavior

QCefWidget can set the initial URL and navigate to a different URL. After being hidden once, setting the URL for a new display causes a full OBS crash.

Steps to Reproduce

  1. Build Own3dPro plugin for OBS 28 https://github.com/StefanEnsmann/own3dpro-obs-plugin/tree/obs28
  2. Open the Theme Selector
  3. Close Theme Selector
  4. Re-open Theme Selector

Anything else we should know?

  • The Qt6 version is built against the dependencies from obs-deps
  • In our codebase there is no significant change that could affect this window apart from the new targeting of Qt6
  • We run into a nullpointer in browser-panel.cpp:430 coming up from CEF
  • The current main version of this plugin is working as expected with OBS 27.2.4, even when compiling with the new build pipeline that supports Qt6 targeting. All changes to this project up until this point can be seen here

  • The original developer of this plugin is not available to work at it at the moment, so we need to fix it up ourselves
  • Our suspicion is that something has changed in the internal resource handling of either the obs-browser plugin or CEF itself that causes the main frame to be missing with our current implementation

tl;dr: We are creating a QDialog that contains a QCefWidget. Hiding this dialog and then re-setting the QCefWidget URL causes a crash in OBS 28, while it works in OBS 27.2.4

@WizardCM
Copy link
Member

Please provide either the crash log or a stack trace from VS. It'll help determine whether the crash is in our own code, or deep within CEF.

@StefanEnsmann
Copy link
Author

Exception thrown at 0x00007FFFC2E3E8D3 (obs-browser.dll) in obs64.exe: 0xC0000005: Access violation reading location 0x0000000000000000.


obs-browser.dll!CefBrowserCToCpp::GetMainFrame() Line 249
	at C:\dev\cef_binary_5060_windows_x64\libcef_dll\ctocpp\browser_ctocpp.cc(249)
obs-browser.dll!QCefWidgetInternal::setURL(const std::string & url_) Line 430
	at D:\obs2\plugins\obs-browser\panel\browser-panel.cpp(430)
own3d.dll!own3d::ui::browser::show() Line 70
	at C:\Users\Stefan\src\own3dpro-obs-plugin\source\ui\ui-browser.cpp(70)
Qt6Core.dll!00007fff7b9594c4()
Qt6Core.dll!00007fff7b95b9a4()
Qt6Gui.dll!00007fff7eb61c91()
Qt6Widgets.dll!00007fff7fd511b9()
Qt6Widgets.dll!00007fff7fd51034()
Qt6Widgets.dll!00007fff7fd570fa()
Qt6Widgets.dll!00007fff7fc0d980()
Qt6Widgets.dll!00007fff7fbd14ae()
Qt6Widgets.dll!00007fff7fbcf5e9()
Qt6Core.dll!00007fff7b920505()
Qt6Widgets.dll!00007fff7fbd50f2()
Qt6Widgets.dll!00007fff7fc2ac0b()
Qt6Widgets.dll!00007fff7fc28d6d()
Qt6Widgets.dll!00007fff7fbd14ae()
Qt6Widgets.dll!00007fff7fbd0674()
Qt6Core.dll!00007fff7b920505()
Qt6Gui.dll!00007fff7e8d4448()
Qt6Gui.dll!00007fff7e9203e8()
Qt6Core.dll!00007fff7ba73f04()
Qt6Gui.dll!00007fff7eb30fa9()
Qt6Core.dll!00007fff7b925874()
Qt6Core.dll!00007fff7b91e57d()
obs64.exe!run_program(std::basic_fstream<char,std::char_traits<char>> & logFile={...}, int argc=2, char * * argv=0x000001aa4de745d0) Line 2340
	at D:\obs2\UI\obs-app.cpp(2340)
obs64.exe!main(int argc, char * * argv=0x000001aa4de745d0) Line 3050
	at D:\obs2\UI\obs-app.cpp(3050)
obs64.exe!WinMain(HINSTANCE__ * __formal=0x0000000000000000, HINSTANCE__ * __formal=0x0000000000000000, char * __formal=0x0000000000000000, int __formal=0) Line 97
	at D:\a\obs-deps\obs-deps\windows_build_temp\qt6\qtbase\src\entrypoint\qtentrypoint_win.cpp(97)
[Inline Frame] obs64.exe!invoke_main() Line 102
	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(102)
obs64.exe!__scrt_common_main_seh() Line 288
	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
kernel32.dll!00007ff811ed54e0()
ntdll.dll!00007ff81378485b()

Thanks for the prompt response. This is the VS stack trace to the point where the nullpointer is coming up. The exception then occurs one step out when trying to call ->LoadURL(...)

@WizardCM
Copy link
Member

Interesting - that crash is within the CEF wrapper's code, rather than in ours directly.

I will look into this when I can, before 28's final release. That code hasn't changed on our side since it was introduced. Interestingly, we don't protect against an invalid GetMainFrame() result in most places, only in the SendBrowserProcessMessage macro.

In the meantime, what happens if you try showing the widget first (so swap lines 70 and 71 in source/ui/ui-browser.cpp) before trying to set the URL?

@WizardCM
Copy link
Member

As a note:

public virtual CefRefPtr<CefFrame> GetMainFrame()= 0;
Returns the main (top-level) frame for the browser. In the browser process this will return a valid object until after CefLifeSpanHandler::OnBeforeClose is called. In the renderer process this will return NULL if the main frame is hosted in a different renderer process (e.g. for cross-origin sub-frames). The main frame object will change during cross-origin navigation or re-navigation after renderer process termination (due to crashes, etc).

@StefanEnsmann
Copy link
Author

Thanks a lot for your support. I swapped the lines and the result is the same. The window opens during the debugging step, but on the setURL afterwards it still crashes with _retval = 0x000....

You beat me to the comment from the source code, was just about to post it here as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants