Rockarolla
Rockarolla

Reputation: 99

Tkinter Spinbox and multiprocessing causes mac SEGFAULT

My application has been failing on OSX when using multiprocessing and tkinter. The minimum example is as easy as follows:

import multiprocessing
from tkinter import Spinbox #Delete this line and it works

class Gui(multiprocessing.Process):

    def run(self):
        self.start_window()
        self.root.mainloop()

    def start_window(self):
        from tkinter import Tk
        self.root = Tk()
        self.root.title('Test')

g = Gui()
g.start()

When trying to execute this snippet mac fails with the following report:

Process: Python [1453] Path: > /Library/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python Identifier: Python Version: 3.4.4 (3.4.4) Code Type: X86-64 (Native) Parent Process: Python [1452] Responsible: Terminal [395] User ID: 501

Date/Time: 2016-01-18 18:33:23.281 +0100 OS Version: Mac OS X 10.11.2 (15C50) Report Version: 11 Anonymous UUID: 49081BD5-7C1E-52F6-E5D9-F9F41BA8DFE5

Time Awake Since Boot: 6200 seconds

System Integrity Protection: enabled

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000110

VM Regions Near 0x110: --> __TEXT 0000000100000000-0000000100001000 [ 4K] r-x/rwx SM=COW /Library/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python

Application Specific Information: * multi-threaded process forked * crashed on child side of fork pre-exec

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libdispatch.dylib 0x00007fff99f0fd69 _dispatch_async_f_slow + 391

1 libxpc.dylib 0x00007fff8fb8daa0 xpc_connection_resume + 192

2 com.apple.CoreFoundation 0x00007fff9bbb69d1 _CFPrefsWithDaemonConnection + 353

Deleting the Spinbox import (not used in the code) makes everything run. The same problem appears on python 3.4.4 and 2.7 (changing tkinter to Tkinter)

Removing the multiprocessing module and making everything run on the same process also makes the problem disappear.

My guess is that I'm violating some Tk/Tcl constrain, but I haven't found anything reading the docs about this, also the fact that this only happens with Spinbox and not with Entry or other widgets is suspicious.

Upvotes: 1

Views: 416

Answers (2)

Rockarolla
Rockarolla

Reputation: 99

I managed to make it work, for some reason tkinter wants to be imported in the same Thread/Process that its executing from.

When extending multiprocess.Proccess the new process code is inside the run() method, the init is executed on the parent process. Therefore changing all the imports to be locally done on the run method fixes the problem.

The example code looks as follows:

import multiprocessing

class Gui(multiprocessing.Process):

    def run(self):
        from tkinter import Spinbox # or Tk, or * ....
        self.start_window()
        self.root.mainloop()

    def start_window(self):
        from tkinter import Tk
        self.root = Tk()
        self.root.title('Test')

g = Gui()
g.start()

Now my application works on Windows, Linux and Mac.

Upvotes: 1

Terry Jan Reedy
Terry Jan Reedy

Reputation: 19184

When I run your code from IDLE editor, on Windows, there is no error, but no tk box either, just the '>>>' prompt in Shell. When I put the end of the code under an if name clause, as specific in the multiprocessing doc

if __name__ == '__main__':
   g = Gui()
   g.start()

a tk box appears. The same is true with only g.start() so protected. Try one or both versions on your Mac. I don't know if this is the only problem on OSX, but it will at least let you start with something that runs on other systems.

Upvotes: 0

Related Questions