wxPython app crashing as a child process using multiprocessing on Mac OS X

256 views
Skip to first unread message

Igor Karpov

unread,
Sep 22, 2011, 4:34:25 PM9/22/11
to wxPython-users
This is an example of something that should work but seems to crash
python on Mac OS X.

The code below contains a simple function that starts a
multiprocessing.Process and establishes a multiprocessing.Queue
to talk to it. The process then creates a simple wxPython app
consisting of a frame with a button. The button puts items onto
the Queue. The main process consumes the items until it sees
the item None, at which it joins the child process and exits.
The item None is sent by the wxPython application when the frame
is closed.

Code:
==================================[ multiwx.py ]========
import wx
from multiprocessing import Process, Queue

class MultiFrame(wx.Frame):
""" A frame with a button """
def __init__(self, parent, title, queue):
wx.Frame.__init__(self, parent, title=title, size=(200,100))
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.button = wx.Button(self, label='Send Text!')
self.button.Bind(wx.EVT_BUTTON, self.OnButton)
self.queue = queue
self.Show(True)

def OnButton(self,e):
""" when the button is pressed, send something to main process
"""
self.queue.put('button!')

def OnClose(self,e):
""" when the window is closing, send None to main process """
print 'closing!'
self.queue.put(None)
self.Destroy()

def start_app(queue):
""" start a wxPython app using queue for multiprocess
communication """
app = wx.App(False)
frame = MultiFrame(None, 'MultiWx', queue)
app.MainLoop()

def main():
""" main function """
q = Queue() # create a queue object to talk to the window
p = Process(target=start_app, args=(q,)) # create the window
process
p.start() # start the window process
while True: # repeat until done
item = q.get() # get the next item from queue
if item is None:
print 'done!' # signal that we are done
break # break out of the loop
else:
print item # print the item from queue
p.join() # wait for the child process to finish

if __name__ == '__main__':
main()
=====================================================

The expected behavior is that every button presses causes
'Button!' to be printed by the main process and the frame
close event causes 'closing!' and 'done!' to be printed and the
program to exit.

On Ubuntu Linux 10.4 Lucid Lynx (x86_64) with Python 2.6.5 and
wx.__version__ 2.8.10.1, script behaves as expected.

On Windows 7 with Python 2.7.2 and wxPython 2.8.12.1, script
behaves as expected.

On Mac OS X 10.6.8 (x86 Intel), the following crash is produced:

Process: Python [408]
Path: /System/Library/Frameworks/Python.framework/Versions/
2.6/Resources/Python.app/Contents/MacOS/Python
Identifier: Python
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: Python [405]

Date/Time: 2011-09-22 15:15:10.459 -0500
OS Version: Mac OS X 10.6.8 (10K549)
Report Version: 6

Interval Since Last Report: 200152 sec
Crashes Since Last Report: 11
Per-App Crashes Since Last Report: 5
Anonymous UUID: EE52D522-
D315-4B44-90E2-6E4E431A94DD

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000b011aff0
Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Application Specific Information:
*** multi-threaded process forked ***

Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 com.apple.CoreGraphics 0x958671b5 _CG_spin_lock_try + 9
1 com.apple.CoreGraphics 0x95866fd9
CGSShmemRWLockLockForReading + 79
2 com.apple.CoreGraphics 0x95866f81 lockDisplay + 45
3 com.apple.CoreGraphics 0x958786e9 CGSMainDisplayID + 122
4 _core_.so 0x005a20ec
wxPyTestDisplayAvailable() + 12
5 _core_.so 0x005ac3d1
wxFindWindowByLabel(wxString const&, wxWindow const*) + 1061
6 org.python.python 0x0000c6e0 PyObject_Call + 101
7 org.python.python 0x0008c843 PyEval_EvalFrameEx +
21688
8 org.python.python 0x0008cf74 PyEval_EvalCodeEx + 1720
9 org.python.python 0x0008b5a1 PyEval_EvalFrameEx +
16918
10 org.python.python 0x0008cf74 PyEval_EvalCodeEx + 1720
11 org.python.python 0x0002ee0c PyClassMethod_New + 1823
12 org.python.python 0x0000c6e0 PyObject_Call + 101
13 org.python.python 0x0001c10d PyClass_New + 1603
14 org.python.python 0x0000c6e0 PyObject_Call + 101
15 org.python.python 0x00053d8a _PyType_Lookup + 5617
16 org.python.python 0x00055bc1 PyType_GenericAlloc +
3133
17 org.python.python 0x0000c6e0 PyObject_Call + 101
18 org.python.python 0x0008c812 PyEval_EvalFrameEx +
21639
19 org.python.python 0x0008cf74 PyEval_EvalCodeEx + 1720
20 org.python.python 0x0002ed9f PyClassMethod_New + 1714
21 org.python.python 0x0000c6e0 PyObject_Call + 101
22 org.python.python 0x0008c843 PyEval_EvalFrameEx +
21688
23 org.python.python 0x0008b4e5 PyEval_EvalFrameEx +
16730
24 org.python.python 0x0008b4e5 PyEval_EvalFrameEx +
16730
25 org.python.python 0x0008cf74 PyEval_EvalCodeEx + 1720
26 org.python.python 0x0002ee0c PyClassMethod_New + 1823
27 org.python.python 0x0000c6e0 PyObject_Call + 101
28 org.python.python 0x0001c10d PyClass_New + 1603
29 org.python.python 0x0000c6e0 PyObject_Call + 101
30 org.python.python 0x00053d8a _PyType_Lookup + 5617
31 org.python.python 0x00055bc1 PyType_GenericAlloc +
3133
32 org.python.python 0x0000c6e0 PyObject_Call + 101
33 org.python.python 0x0008c812 PyEval_EvalFrameEx +
21639
34 org.python.python 0x0008b4e5 PyEval_EvalFrameEx +
16730
35 org.python.python 0x0008b4e5 PyEval_EvalFrameEx +
16730
36 org.python.python 0x0008cf74 PyEval_EvalCodeEx + 1720
37 org.python.python 0x0008d019 PyEval_EvalCode + 87
38 org.python.python 0x000a40af Py_CompileString + 111
39 org.python.python 0x000a415b PyRun_FileExFlags + 139
40 org.python.python 0x000a5e7e PyRun_SimpleFileExFlags
+ 814
41 org.python.python 0x000b315c Py_Main + 3074
42 org.python.python.app 0x00001eb5 start + 53

Robin Dunn

unread,
Sep 26, 2011, 1:16:21 PM9/26/11
to wxpytho...@googlegroups.com
On 9/22/11 1:34 PM, Igor Karpov wrote:
> This is an example of something that should work but seems to crash
> python on Mac OS X.
>
> The code below contains a simple function that starts a
> multiprocessing.Process and establishes a multiprocessing.Queue
> to talk to it. The process then creates a simple wxPython app
> consisting of a frame with a button. The button puts items onto
> the Queue. The main process consumes the items until it sees
> the item None, at which it joins the child process and exits.
> The item None is sent by the wxPython application when the frame
> is closed.

I expect that at least part of the problem is the restrictions that OSX
places on applications that try to access the GUI Display. Since the
child process being run is not a full application bundle then it is
having a problem when it tries to create the wx.App, and then something
that is trying to deal with that problem is crashing. If you keep the
GUI in the main process and move the queue processor to the child
process then it works fine

--
Robin Dunn
Software Craftsman
http://wxPython.org

mp.py

Igor Karpov

unread,
Sep 30, 2011, 12:04:24 PM9/30/11
to wxPython-users
Hello Robin,

Thanks for your reply!

Yes, indeed, if I run the GUI in the main process, it will work fine.
However, what I really need this for is something that is written in C+
+ and already has its own GUI. It also *embeds* Python, so I thought
that this would allow me to easily create secondary windows to show
temporary additional information to the user. Because of this, I can't
really make the wx GUI thread central to the application.

Another thing that worries me is that this is an instance where
wxPython is breaking the cross-platform ideal - it works fine on
Windows and Linux, but breaks horribly on Mac. I know there are
several other things in Python that are system-dependent, but at the
very least I think this should fail more gracefully and/or be
documented to warn people like me =).

Do you or anyone know of an appropriate place to file this as a bug? I
tried once before posting on this list, but couldn't figure out where
to do it...

Thanks again,

--Igor.
>  mp.py
> 1KViewDownload
Reply all
Reply to author
Forward
0 new messages