
GameWindow() Crashing in SVN on Linux
Posted Monday, 17 March, 2008 - 19:40 by Hangar inOkay, so I don't know whether SVN is stable on Linux right now or if it's my drivers (I'm not 100% sure how stable the drivers are) but I thought I'd check here for some help. 0.9.0 works fine, but I was hoping to use some of the new stuff early. If it turns out to be a problem, it's no biggie, I just want to get this resolved (on my end) before 0.9.1 is released.
I'm running Debian (Lenny) Linux on an ASUS EEE PC, using mono 1.9, though 1.2.6 had similar problems. The ASUS EEE PC has an underclocked 900MHz processor, 800x480 screen and GMA900 graphics card. It might be exposing an edge case, or it could be my setup.
I get two errors. The first is when I run the examples, I get random segfaults that are fairly random. The examples all work, (well, the ones my graphics card supports do), but sometimes when I start up an example, the program crashes. Here's the head of the error report. I'll post more if you think it's useful:
Launching example: Examples.WinForms.W02_Immediate_Mode_Cube Display: 138706688, Screen: 0, RootWindow: 105 Creating GraphicsContext. GraphicsMode: Index: 37, Color: 32 (8888), Depth: 24, Stencil: False, Samples: 0, Accum: 0 ( indexed), Buffers: 2, Stereo: False IWindowInfo: X11.WindowInfo: Display 138706688, Screen 0, Handle 35652074, Parent: (null) Chose visual: id (37), screen (0), depth (24), class (TrueColor) Creating OpenGL context: direct, not shared... Stacktrace: at (wrapper managed-to-native) OpenTK.Platform.X11.Glx.CreateContext (intptr,OpenTK.Platform.X11.XVisualInfo&,intptr,bool) <0x00004>
It appears to originate in the GLControl() constructor
The second error is segfault that appears when I let a program involving a GameWindow() close. Here's some Boo code that reproduces it:
import OpenTK import System import System.Threading window = GameWindow() window.Dispose() window = null print "Finished.\n" GC.Collect(2) print "Collected.\n"
It prints out both "Finished." and "Collected." but then segfaults. It doesn't matter if I don't include the Dispose() call or the GC collection. Depending on variations of the program, I get different error messages, but I think this is the important part of the stack trace:
at (wrapper managed-to-native) OpenTK.Platform.X11.Glx.MakeCurrent (intptr,intptr,intptr) <0x00004> at (wrapper managed-to-native) OpenTK.Platform.X11.Glx.MakeCurrent (intptr,intptr,intptr) <0xffffffff> at OpenTK.Platform.X11.X11GLContext.Dispose (bool) <0x00027> at OpenTK.Platform.X11.X11GLContext.Finalize () <0x0000f>
Looking at the code, it appears that the Glx.MakeCurrent call is being called on currentWindow.Display when the currentWindow.Display is somehow invalid. So it must be that the finalizer is assuming deterministic finalization and not getting it. But further than that, I don't understand the control flow enough to figure out where to look to fix it.


Comments
Re: GameWindow() Crashing in SVN on Linux
Thanks for the report. Actually I am fighting with this problem right now and it's good to know it's not only a problem on my configuration.
The control flow has changed a lot since 0.9.0 - in SVN it works like this:
I'm no xlib expert, but I think I can there are two issues at play here:
Glx.CreateContext: I *think* this has to do with the display connection being invalid. Documentation is somewhat sparse (can you query/create a visual in one connection and use it in another?), so it's mostly a matter of educated guesses.Glx.MakeCurrenton shutdown. I think I've discovered the cause (a moment of clarity while commuting to work :) ) - the finalizer thread is called on a different thread, which *may* cause problems (once more, docs are somewhat sparse).If you have any ideas I'd love to hear them! I consider this a blocking issue for 0.9.1 (which will be released shortly after this is resolved). :)
Re: GameWindow() Crashing in SVN on Linux
For 1) I have no idea; I haven't worked all that much with glx.
For 2) It took me so long to notice, but GameWindow.Dispose() doesn't do anything right now; it should probably call DisposeInternal() by default. No wonder mono was calling the finalizer in my code.
The problem is definitely that either the display handle is no longer valid or that currentWindow is gone.
Also, calling window.Context.Dispose() manually, I was able to get it to die at a different spot:
So it looks like there's more than one race condition in the finalization code.
Re: GameWindow() Crashing in SVN on Linux
I have made some potential fixes to GameWindow/X11, and it no longer crashes on Mesa3d/software (I still see intermittent crashes on Ati/fglrx).
Can you please checkout and test if it still crashes?
Re: GameWindow() Crashing in SVN on Linux
I went back to mono 1.2.6 because the installer version of monodevelop 1.0 was unstable on my system and haven't seen any crashes lately, but in a little while I'll go back to the installer version and run a bunch of tests. Gotta get something done on my project first (holding up a team member right now).
Re: GameWindow() Crashing in SVN on Linux
Thanks :)
Re: GameWindow() Crashing in SVN on Linux
It's a lot more stable now. The first issue, which appeared when I tested the examples, is no longer present. The second issue is also gone, but I can get it to produce another similar error.
Running this code:
I get this out:
If I uncomment the window.Context.Dispose() line, the problem goes away. The number of successful loops varies as I modify the test. If I comment out any of the other lines (besides the one that creates the GameWindow), the problem is still present.
I guess System.Windows.Forms.XplatUIX11.HandleError is handling the uncaught exception from the finalizer, and the real error is a duplicated add to a dictionary. My impression is that some code you wrote to keep track of the contexts is adding some contexts multiple times under some strange circumstances.
Hope this helps.
Re: GameWindow() Crashing in SVN on Linux
Thanks, this sheds some light to what is happening.
Your analysis looks solid: the context is not destroyed at the correct time, which causes problems when creating a new one (the new one is added before the first one is removed from the list of contexts).
Edit: I am not able to reproduce the exception. Here, it completes the stress test without issue:
It does crash if I remove the call to
gw.Dispose()however. Investigating...Edit 2:
I've updated GameWindow to throw an ObjectDisposedException in this case:
The first line disposes the context internally. I'm still not able to reproduce the problem...
Edit 3:
I can reproduce the exception only if I do *not* call
gw.Dispose(). This means the problem lies in the GraphicsContext finalizer.Edit 4:
Ok, what happens if you replace this line:
with this?
Edit 5 (and final :)):
Ok, there are two solutions for all these problems (from the perspective of OpenTK):
new Thread().Start(GameWindow.Run);and blow everything up).Initialize X11 in multithreaded mode with XInitThreads.
I am going for the second approach, and indeed it looks like the race conditions are alleviated (stress tests completes succesfully). There's a *lot* of work to do before OpenTK becomes trully thread safe, but thankfully this can be introduced gradually - not many users are going to create/destroy 100 GameWindows :)
Re: GameWindow() Crashing in SVN on Linux
The stress test was initially just a way to force a natural garbage collection. It appeared that the original crash occurred when finalizers were run at program exit, but I wasn't sure. Having lots of GameWindows appears to be a good way to make race conditions come to light.
Looking at the code, GameWindow.Dispose() doesn't seem to do anything. In SVN it's a no-op:
http://opentk.svn.sourceforge.net/viewvc/opentk/trunk/Source/OpenTK/Game...
Maybe you have it fixed locally?
Re: GameWindow() Crashing in SVN on Linux
Oops yes. Just commited.