Segmentation fault after call to wx.app on Mac OS X

397 views
Skip to first unread message

bcarey

unread,
Jun 8, 2017, 10:58:56 AM6/8/17
to wxPython-users
Greetings,

I am getting a segmentation fault:
~/anaconda/bin/pythonw: line 3: 71574 Segmentation fault: 11  ~/anaconda/python.app/Contents/MacOS/python "$@"

after a call to wx.App(None) which I use to open a file dialog and load a set of data. The file dialog process works fine and appears to close without incident. The segmentation fault comes later in the program when I try to plot some data using pylab.show(). I use the frame.Destroy() command within a function that is used to open and close the file dialog, but it appears that this is persisting and causing the segmentation fault. The code works fine on a Windows machine but fails on my Mac. Please see the attached code fragment that reproduces the problem on my Mac. 

I've installed python 2.7 through anaconda. In order to run this problem, I've added modules wxpython and python.app. I am running the problem from the command line with pythonw. 

I suspect that the problem is that I am not using event handlers. If this is the case, I would appreciate some guidance on how to implement an event handler as I am new to python. Otherwise, any advice on the problem would be most appreciated. 

Thanks,
Bill

Mac OSX 10.11.6


 
temp3.py

bht

unread,
Jun 8, 2017, 12:56:56 PM6/8/17
to wxPython-users
I have not looked at your code, but seg faults are pretty common on Macs when a widget is destroyed before all delayed actions using it are complete. I have seen this oh so many times on the Mac, with code that runs fine in Linux and Windows.

I use wx.CallAfter(...) or sometimes that is not good enough and wx.CallLater(100,...) (for 0.1 sec delay) is needed for routines that will destroy wx widgets.

Hope this fixes your problem.

Brian

bcarey

unread,
Jun 8, 2017, 2:05:52 PM6/8/17
to wxPython-users
Hello Brian,
Thanks very much. Yes, this solved my problem. In the code I attached above, I changed 

app.disconnect()

to 

wx.CallLater(100,app.Disconnect,1)

I don't know what I am doing with the "1" at the end of the function argument list, except that I needed it to avoid an error message:

Traceback (most recent call last):
  File "/Users/bcarey/anaconda/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_misc.py", line 1367, in Notify
    self.notify()
  File "/Users/bcarey/anaconda/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", line 16870, in Notify
    self.result = self.callable(*self.args, **self.kwargs)
  File "/Users/bcarey/anaconda/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_core.py", line 4189, in Disconnect
    return _core_.EvtHandler_Disconnect(*args, **kwargs)
TypeError: Required argument 'id' (pos 2) not found

Hopefully that addition isn't creating problems. 

Thanks for your help!
Bill

Dietmar Schwertberger

unread,
Jun 8, 2017, 3:09:20 PM6/8/17
to wxpytho...@googlegroups.com
On 6/8/17 6:56 PM, bht wrote:
> I have not looked at your code, but seg faults are pretty common on
> Macs when a widget is destroyed before all delayed actions using it
> are complete.
Ah, that explains why I recently had to insert CallAfter/CallLater
workarounds for wxGlade, which is heavily creating and destroying controls.
It would be nice if there was a more deterministic way.
I have never used Mac OS for anything else, but I would assume that this
is wx specific, right?
Would you know how to prepare a sample and submit a bug report for wx
and/or wxPython? I think that would be a major benefit for the platform.

Regards,

Dietmar

Tim Roberts

unread,
Jun 8, 2017, 6:38:56 PM6/8/17
to wxpytho...@googlegroups.com
Hold on a minute -- it's more complicated than that. It's easy to
assume that, just because code happens to run OK on Windows, that the
code must be correct. That's not so. Windows is somewhat resilient to
actions that the other platforms do not accept. The fact is that your
Python code is trying to use a resource after it has been deleted. I
think one can argue that this is a user problem, not a library problem.

I've just finished porting a rather large Windows app to wxWidgets
(C++), which now runs on Windows, Linux, and MacOS. I found a HUGE
number of cases where something that worked just fine on Windows failed
on both Linux and MacOS, but in all but a very few cases, I was doing
things that are warned against in the docs. It was my experience that
Linux was the most finicky of the three, but MacOS has its share of
pickiness as well.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Steve Barnes

unread,
Jun 9, 2017, 3:26:06 AM6/9/17
to wxpytho...@googlegroups.com
Maybe a part of the answer would be to patch the wxWidgets code with a
few additional #warn compiler directives for the cases that can be
detected at compile time and some more run-time warnings for those cases
that you can "get away with" on some platforms and not others, (rather
than just relying on warnings the manuals which tend to be spotted after
the fact).

One tip for anybody is that running with python rather than pythonw
often lets you see warnings that are being output but of course you
never see under pythonw. Also, even if you have produced an executable
with py2exe, pyinstaller, cx_freeze, etc., if you run it from a command
line in a console you will get to see error messages, etc. that are lost
otherwise.

Logging a on crash handers are of course invaluable of course but for me
rule number one in compiled languages is ZERO WARNINGS, not by turning
them off either. Of course static checkers such as pylint are invaluable.

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

Tim Roberts

unread,
Jun 9, 2017, 1:30:57 PM6/9/17
to wxpytho...@googlegroups.com
Steve Barnes wrote:
> Maybe a part of the answer would be to patch the wxWidgets code with a
> few additional #warn compiler directives for the cases that can be
> detected at compile time and some more run-time warnings for those cases
> that you can "get away with" on some platforms and not others, (rather
> than just relying on warnings the manuals which tend to be spotted after
> the fact).

That's a nice thought, but virtually every case I encountered was a
threading or concurrency issue, and that's something that simply cannot
be diagnosed at compile time.

bht

unread,
Jun 9, 2017, 1:51:02 PM6/9/17
to wxPython-users
I find the need to use CallAfter/CallLater on OS X to be quite a pain. I have never seen this spelled out as a wx coding rule, but it seems that any routine that responds to a Bind should never destroy any widget, because there could still be pending events for that widget. These actions need to be placed into routines that are invoked via a CallAfter/CallLater. This can make code reuse tough.

The fact that an event linked to a destroyed widget will crash Python makes debugging these problems really tough. I have spent days tracking down obscure but consistent crashes. I am not sure if the Seg Fault happens inside wxwidgets or wxPython, but if there were any way to trap these "bad" events, it would make wxPython oh so much more pleasant.

Robin Dunn

unread,
Jun 12, 2017, 2:14:15 PM6/12/17
to wxpytho...@googlegroups.com
bht wrote:
I find the need to use CallAfter/CallLater on OS X to be quite a pain. I have never seen this spelled out as a wx coding rule, but it seems that any routine that responds to a Bind should never destroy any widget, because there could still be pending events for that widget. These actions need to be placed into routines that are invoked via a CallAfter/CallLater. This can make code reuse tough.

The fact that an event linked to a destroyed widget will crash Python makes debugging these problems really tough. I have spent days tracking down obscure but consistent crashes. I am not sure if the Seg Fault happens inside wxwidgets or wxPython, but if there were any way to trap these "bad" events, it would make wxPython oh so much more pleasant.

There is a DestroyLater method that is intended for use in these situations. Fundamentally, it is very similar to calling Destroy via a wx.CallAfter, but I expect that since DestroyLater is expressly intended for this purpose that it may be a little easier to remember to use it.

https://docs.wxpython.org/wx.Window.html?highlight=destroylater#wx.Window.DestroyLater

DestroyLater(self)

Schedules the window to be destroyed in the near future.

This should be used whenever Destroy could happen too soon, such as when there may still be events for this window or its children waiting in the event queue.




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

Dietmar Schwertberger

unread,
Jun 12, 2017, 4:42:38 PM6/12/17
to wxpytho...@googlegroups.com
On 6/12/17 8:14 PM, Robin Dunn wrote:
> There is a DestroyLater method that is intended for use in these
> situations. Fundamentally, it is very similar to calling Destroy via a
> wx.CallAfter, but I expect that since DestroyLater is expressly
> intended for this purpose that it may be a little easier to remember
> to use it.
Thanks a lot. I did just a quick test and this seems to fix the problem
for me.
I would have prefered if pending events on destroyed widgets would just
get ignored, though.

Regards,

Dietmar

Tim Roberts

unread,
Jun 13, 2017, 2:39:04 AM6/13/17
to wxpytho...@googlegroups.com
On Jun 12, 2017, at 1:42 PM, Dietmar Schwertberger <mail...@schwertberger.de> wrote:
>
> Thanks a lot. I did just a quick test and this seems to fix the problem
> for me.
> I would have prefered if pending events on destroyed widgets would just
> get ignored, though.

You can't do that, that's way too dangerous. If there are events with no one to handle them, it is an error and needs to be flagged.

Reply all
Reply to author
Forward
0 new messages