Crash exiting MainLoop()

Hello,

I’ve got an application written in Python 3.7 using wxPython 4.0.7.post2 running on Windows 7 and 10. About 25% of the time I exit my program the Python interpreter crashes trying to leave MainLoop(). I usually get an error code like (0xC0000005). If I look in the Windows 10 event viewer I can see the program crash and it indicates that the module the fault happened in was wxbase30u_vc140_x64.dll.

My method that handles wx.EVT_CLOSE has:


print(‘Calling destroy’)
self.DestroyLater()
print(‘Called Destroy’)

I get both of the messages printed. But no further messages are printed at the point that MainLoop() should exit.

The application is too large to post here (~50k LOC). Is there a way to get more information about the crash? Debug into the DLL’s? Anything that could help me track this down?

Thank you!

What does the rest of the EVT_CLOSE handler look like? Does it call event.Skip()? If so, then it is probably due to the C++ part of the frame being destroyed twice.

There are .pdb files available at https://extras.wxpython.org/wxPython4/extras if you want to try to debug into the wrapper code.

Hi Robin,

The close handler does a bit of work to close active network connections, closes a MDI child window, then calls self.DestroyLater() . The event passed into the close handler is not accessed at all.

I’ve pulled down the pdb files and the appropriate source. The problem appears to be in Event.cpp, but I had the wrong source downloaded for that crash, so I don’t know where the real crash is exactly yet. Once I figure that out I’ll likely be back with more questions.

Thanks!

Using the debug files I’ve been able to tell that the crash is happening because a wx.Timer is trying to process an event. I’ve called Stop() and DeletePendingEvents() on all of the wx.Timers I create in my code. Is there any way to stop all wx.Timers() or destroy them in a safe way as part of shutdown? Is there a way to get a list of all wx.Timer objects?

Thanks!

If you use Python Timer the interpreter only stops after all timers have expired, so there will be no crash. The problem is only in the timer handler you have to query the existence of the C++ objects by inserting __nonzero__()

If a frame with a timer is destroyed while the timer is still running, then you do get a crash. That happens even if the event handler doesn’t reference any wrapped C++ objects.

An EVT_WINDOW_DESTROY handler on the frame that stops timers helps with that. Don’t forget event.Skip().

Well, I was actually referring to a Python Timer (see docu of python): that is simply a thread in python, which happens here to be the wrapper of wx. You can destroy as many frames as you like as long as you don’t catch such events as you mentioned the wrapper will happily rap away, I hope :astonished:

Do you mean threading.Timer? How do you get that to play nice with wx, seeing as you can’t touch wx objects from an auxiliary thread?

Yes, I have just uploaded an example under this post

I’m sorry, but that’s not sound: In my_fast_select.py, you are calling wx.StatusBar.SetStatusText from a different thread, not the wx main thread, and that will get you in trouble.

Well, what you say is what the wx docu advises, though in less drastic words. This thread started off with a C++ part still running (the timer still firing) at shut down of the wrapper and, of course, posting more events correctly from a thread doesn’t alleviate the situation, not a bit.

So let’s be correct and wait… :sneezing_face:

and using ‘CallLater’ may cause hiccups: that object may be thread-safe, but it’s definitely not class-safe

problem.py (1.3 KB)

and it’s easy to flood the GUI, but a good Window Manager won’t crash (poorly written apps though may)

colour_pump.py (3.5 KB)

the larger the Frame the quicker the manager is puffed (a clear reminder that one is at a work station and not play station)