-
Notifications
You must be signed in to change notification settings - Fork 606
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
Hack to fix singleplayer crashing when toggling fullscreen. #1037
base: master
Are you sure you want to change the base?
Conversation
Fixes #1036 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d rather we don’t introduce more hacks. Why do we need to memset on restart? What’s the actual cause of the crash?
OpenJK/code/rd-vanilla/tr_init.cpp Line 708 in 5203023
This line falls through to GL_SetDefaultState() because glConfig.vidWidth is never reset to 0. This is the message printed upon crashing: It seems like the codebase relies on dlclose(rdsp-vanilla.so) and dlopen to reset glConfig.vidWidth to 0. OpenJK/code/client/cl_main.cpp Line 901 in 5203023
Setting a breakpoint here on the equivalent multiplayer file shows that glConfig, correctly, goes away after dlclose(). multiplayer:
single player shows glConfig is still around after dlclose():
|
My guess as to a real fix might be to make the singleplayer codebase more similar to multiplayer codebase. One of the biggest differences I see is singleplayer's cl_main: singleplayer: OpenJK/code/client/cl_main.cpp Line 87 in 5203023
multiplayer: OpenJK/codemp/client/cl_main.cpp Line 120 in 5203023
I tried to refactor to make singleplayer define re as a pointer, but this might be a red herring. It did not fix the problem. from dlclose(3):
I only see a single call to dlopen so maybe some dependency is keeping the reference count > 0? Is is true that the codebase relies on dlclose and dlopen to reset glConfig to 0? Somewhat related is this suggestion:
Source: android/ndk#887 (comment) It is strange that multiplayer fullscreening works but singleplayer does not, since multiplayer does not have my hack. |
Useful breakpoint set here for multiplayer after toggling fullscreen. It shows how glConfig is a global that should be initialized to 0 at some point. I can't really pinpoint the exact point, but maybe after the dlclose -> dlopen sequence? OpenJK/codemp/rd-vanilla/tr_init.cpp Line 796 in 5203023
|
I did some digging around and found that There is apparently a way of avoiding this by compiling with |
OpenBSD port uses clang, but clang didn't compile complaining about not recognizing Full build log where cc -> egcc (gcc 8.3.0) https://gist.github.com/namtsui/f60b0d6fe9d334c3b6b30d1541645058 |
3edc1b1
to
896777f
Compare
I force pushed a more concise one-liner hack for consideration. It uses the
|
As an aside, I had to comment out printing out the renderer_string because I was getting segfaults where renderer_string contains garbage or memory I could not access. This happens when toggling fullscreen. I'm not sure why nor if this is related to the original issue.
|
Here is an update to #1037 (comment) which was slightly inaccurate. glConfig.renderer_string only needed to be commented out when I was initially investigating fullscreen segfaulting. With the one-liner hack, renderer_string properly prints out as |
I think in both SP and MP we should have these conditions if destroyWindow is true: and after the window shutdown func pointer memset glconfig & glconfigext (might be MP exclusive) Is there ever a time where restarting happens without destroy window? Changing from full to not full and vice versa will require a destroy window afaik. For reference see: https://github.com/etfdevs/ETe/blob/master/src/renderer/tr_init.c#L2003-L2005 cc @xycaleth possibly even clear the |
SP and MP fullscreen toggling both work in my testing with the changes that you proposed. I did get an unrelated segfault that I can't seem to reproduce and was not running gdb for. In multiplayer I created a game on Vjun Sentinel, got the Merr-Sonn PLX-2M behind the lifts near the starting spawn at lifts, and immediately segfaulted after firing it. However, now I can fire without segfaulting. I'll open an issue if I see it again. Reported here: #1038
I observed the following scenarios for destroyWindow and restarting:
|
So basically it cannot be false, true. Which is ideal and why the new fix should probably be accepted I guess l. |
Fixes JACoders#1036 Unbreaks crash when toggling fullscreen in the singleplayer binary on OpenBSD. openjk (multiplayer binary) uses -lGL and -lGLU but openjk_sp did not.
@xycaleth @ensiform This is ready for review with a proper fix. I have output from both LD_DEBUG=1 openjk_sp and openjk on OpenBSD at this link. I noticed that openjk (multiplayer binary) has a direct dependency on libGL.so and libGLU. This was not the case for openjk_sp, where libGL.so and libGLU.so first gets loaded by rdsp-vanilla.so. This explains (in a handwavy way) the strange behavior for dlopen and dlclose and its interaction with ld.so(1) on OpenBSD.
Adding -lGL and -lGLU to cmake, as done with the multiplayer binary, resolves the issue. Toggling singleplayer fullscreen no longer crashes on OpenBSD. |
Unbreaks crash when toggling fullscreen in openjk_sp (singleplayer binary). openjk (multiplayer binary) is linked with -lGL -lGLU, but openjk_sp lacks these flags. see: JACoders/OpenJK#1037 ok bcallah@ and tobhe@
Unbreaks crash when toggling fullscreen in openjk_sp (singleplayer binary). openjk (multiplayer binary) is linked with -lGL -lGLU, but openjk_sp lacks these flags. see: JACoders/OpenJK#1037 ok bcallah@ and tobhe@
Unbreaks crash when toggling fullscreen in openjk_sp (singleplayer binary). openjk (multiplayer binary) is linked with -lGL -lGLU, but openjk_sp lacks these flags. see: JACoders/OpenJK#1037 ok bcallah@ and tobhe@
thanks for reviewing |
glConfig is a global variable visible to tr_{model,init}.cpp and not
visible to cl_main.cpp, which has its own global cls.glconfig. When
RE_BeginRegistration is being called while the video subsystem is
restarting, explicitly memset glConfig to 0. InitOpenGL depends on
glConfig.vidWidth == 0.
In the codemp/ version, Sys_UnloadDll (dlclose) is sufficient to
remove glConfig, which gets reset to 0 later on. In the code/ version,
even after Sys_UnloadDll (dlclose), the old glConfig and vidWidth
remain, so InitOpenGL fails.