We have been looking further into the crashes on SIGINT and other signals, especially after a recent post from Fernando Perez at comp.lang.python*.
Here is a summary and our conclusions, but with the disclaimer that we have limited understanding of the inner workings of Python and wxPython. This is a serious issue since it not only affects SIGINT but all signals and renders the Python signal module almost useless with wxPython.
After import wxPython, setting the signal handler for SIGINT back to the Python default_int_handler seems to be working. It generates a SystemError exception which is ignored but which should not happen, obviously.
Setting the signal handler for SIGINT back to SIG_IGN or setting any signal handler to SIG_IGN or SIG_DFL also results in an exception, but a TypeError. Hitting Cltr+C at that time results in a crash, consistently and repeatably.
It is unclear what the actual signal handler is for SIGINT and what is causing the TypeError and SystemError, but it is quite clear that both are symptoms of an underlying problem.
The traceback** indicates that the crash occurs at Py_INCR(x) in the Python source file Python/ceval.c on line 2493 in function PyEval_EvalCodeEx(). The value of one of the args is NULL instead of the handler for SIGINT. Note, this is after the SIGINT handler is reset to SIG_IGN or SIG_DFL.
Also, wxPython function __wxPreStart() in file wxPython/src/helpers.cpp calls Python function PyOS_FiniInterrupts() which is in the signalmodule.c file. The latter restores all signal handlers to their original state and wipes out the C globals used in the signalmodule.c which were initially set by Py_InitInterrupts(). In particular globals IntHandler, IgnoreHandler, and DefaultHandler are set to NULL by PyOS_FiniInterrupts().
This does not look like a bug in Python. Rather, wxPython should not call PyOS_FiniInterrupt(). Instead, wxPyhon should call other Python signal functions to achieve what wxPython needs (is that just resetting the SIGINT handler to SIG_IGN?). Or maybe call PyOS_InitInterrupts() again to re-initialize the globals Python needs (but may cause other problems, like redefining all attributes of the Python signal module).
Both suggestions are guesses on our part, but we do suspect that the call to PyOS_FiniInterrupts() is the root cause of the signal crashes. And that call breaks all further signal handling in Python, forever.
We are looking forward to your take on this and corrections of any misunderstanding on our part.
About two months ago, we exchanged a couple of posts about handling interrupt in a wxPython application. In the mean time, we have done a little more work on this issue and the results are below.
We copied the clearSigInt code from wx.App.__init__ in 2.5.x to our App.OnInit() method and tried different cases as indicate by the numbered comments below.
class App(wx.App):
....
def OnInit(self):
# copied from wx.App.__init__() in wxPython 2.5.x
# file wxPythonSrc-2.5,x/wxPython/src/_app_ex.py
if True: # clearSigInt:
try:
import signal
#1 signal.signal(signal.SIGINT, signal.SIG_DFL) # behaves as expected
#2 signal.signal(signal.SIGINT, signal.SIG_IGN) # surprise, Ctrl-C does interrupt
#3 signal.signal(signal.SIGINT, signal.default_int_handler) # crashes on Ctrl+C
except:
pass
It turns out that both cases #1 and #2 behave exactly the same as the default behavior in wxPython 2.4.1.2: hitting Ctrl+C in the terminal window interrupts the application, always. This is unexpected for case #2, since Ctrl+C should have no effect.
However, case #3 crashes the application with a segmentation fault after Ctrl+C is typed in the terminal window. Attached is the traceback from the core file and it does appear that there is a problem in Python. But it does not seem to be related to SIG_DFL being zero, as far as we can tell.
In addition, printing the value returned by the signal.signal() call does not show anything, not 0, not 1, nothing. It looks like an empty string but repr() does not show anything either.
We are not sure what to make of this and hope this might be helpful to you.
/Jean Brouwers
ProphICy Semiconductor, Inc.
PS) This is wxPython 2.4.1.2 and Python 2.3 on RedHat Linux 8 with GTK2.
Robin Dunn wrote:
Jean Brouwers wrote:
What about this surprise?
Test #1
$ python
Python 2.3 (#3, Jul 30 2003, 15:13:26)
[GCC 3.2 20020903 (Red Hat Linux 8.0 3.2-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import signal
>>> signal.getsignal(signal.SIGINT)
<built-in function default_int_handler> # as expected
>>> import wx
>>> signal.getsignal(signal.SIGINT)
Segmentation fault (core dumped) # wow!
Yep. This is a bug in Python. wx.App.__init__ sets the signal handler to SIG_DFL (which is zero in C) and then when you call getsignal Python tries to turn the pointer it gets (NULL) into a PyObject to return. It would normally be some callable python object, but in this case Python ends up dereferencing a NULL pointer and crashing.
I'm pretty sure I entered this into the Python bug tracker, or found it there already, although I can't find it right now. If you have time you might try looking for it and entering it again if not found so it can be fixed before 2.4.
------------------------------------------------------------------------
Traceback of the segmentation fault after Ctrl+C when restoring the default SIGINT
handler with signal.signal(signal.SIG_INT, signal.default_int_handler) in the OnInit()
method of the main App(wx.App) class of a Python 2.3 and wxPython 2.4.1.2 application.
/Jean Brouwers
ProphICy Semiconductor, Inc.
[ProphICy ~/src]$ gdb /ProphICy/bin/python core.23994
GNU gdb Red Hat Linux (5.2.1-4)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
warning: core file may not match specified executable file.
Core was generated by `/ProphICy/bin/python runGui.py ..'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libpthread.so.0...done.
Loaded symbols for /lib/i686/libpthread.so.0
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libutil.so.1...done.
Loaded symbols for /lib/libutil.so.1
Reading symbols from /usr/lib/libstdc++.so.5...done.
Loaded symbols for /usr/lib/libstdc++.so.5
Reading symbols from /lib/i686/libm.so.6...done.
Loaded symbols for /lib/i686/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/strop.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/strop.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/time.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/time.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/cStringIO.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/cStringIO.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/fcntl.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/fcntl.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/select.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/select.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/termios.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/termios.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/resource.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/resource.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_socket.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_socket.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_ssl.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_ssl.so
Reading symbols from /lib/libssl.so.2...done.
Loaded symbols for /lib/libssl.so.2
Reading symbols from /lib/libcrypto.so.2...done.
Loaded symbols for /lib/libcrypto.so.2
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_weakref.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_weakref.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/operator.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/operator.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/math.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/math.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/itertools.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/itertools.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/cPickle.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/cPickle.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/wxc.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/wxc.so
Reading symbols from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so...done.
Loaded symbols for /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
Reading symbols from /usr/lib/libgtk-x11-2.0.so.0...done.
Loaded symbols for /usr/lib/libgtk-x11-2.0.so.0
Reading symbols from /usr/lib/libgdk-x11-2.0.so.0...done.
Loaded symbols for /usr/lib/libgdk-x11-2.0.so.0
Reading symbols from /usr/lib/libatk-1.0.so.0...done.
Loaded symbols for /usr/lib/libatk-1.0.so.0
Reading symbols from /usr/lib/libgdk_pixbuf-2.0.so.0...done.
Loaded symbols for /usr/lib/libgdk_pixbuf-2.0.so.0
Reading symbols from /usr/lib/libpangoxft-1.0.so.0...done.
Loaded symbols for /usr/lib/libpangoxft-1.0.so.0
Reading symbols from /usr/lib/libpangox-1.0.so.0...done.
Loaded symbols for /usr/lib/libpangox-1.0.so.0
Reading symbols from /usr/lib/libpango-1.0.so.0...done.
Loaded symbols for /usr/lib/libpango-1.0.so.0
Reading symbols from /usr/lib/libgobject-2.0.so.0...done.
Loaded symbols for /usr/lib/libgobject-2.0.so.0
Reading symbols from /usr/lib/libgmodule-2.0.so.0...done.
Loaded symbols for /usr/lib/libgmodule-2.0.so.0
Reading symbols from /usr/lib/libgthread-2.0.so.0...done.
Loaded symbols for /usr/lib/libgthread-2.0.so.0
Reading symbols from /usr/lib/libglib-2.0.so.0...done.
Loaded symbols for /usr/lib/libglib-2.0.so.0
Reading symbols from /usr/lib/libpangoft2-1.0.so.0...done.
Loaded symbols for /usr/lib/libpangoft2-1.0.so.0
Reading symbols from /usr/X11R6/lib/libXi.so.6...done.
Loaded symbols for /usr/X11R6/lib/libXi.so.6
Reading symbols from /usr/X11R6/lib/libXext.so.6...done.
Loaded symbols for /usr/X11R6/lib/libXext.so.6
Reading symbols from /usr/lib/libXft.so.2...done.
Loaded symbols for /usr/lib/libXft.so.2
Reading symbols from /usr/X11R6/lib/libXrender.so.1...done.
Loaded symbols for /usr/X11R6/lib/libXrender.so.1
Reading symbols from /usr/lib/libfontconfig.so.1...done.
Loaded symbols for /usr/lib/libfontconfig.so.1
Reading symbols from /usr/X11R6/lib/libX11.so.6...done.
Loaded symbols for /usr/X11R6/lib/libX11.so.6
Reading symbols from /usr/lib/libfreetype.so.6...done.
Loaded symbols for /usr/lib/libfreetype.so.6
Reading symbols from /usr/lib/libexpat.so.0...done.
Loaded symbols for /usr/lib/libexpat.so.0
Reading symbols from /usr/X11R6/lib/X11/locale/common/xlcUTF8Load.so.2...done.
Loaded symbols for /usr/X11R6/lib/X11/locale/common/xlcUTF8Load.so.2
Reading symbols from /lib/libnss_files.so.2...done.
Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /usr/lib/gtk-2.0/2.0.0/engines/libbluecurve.so...done.
Loaded symbols for /usr/lib/gtk-2.0/2.0.0/engines/libbluecurve.so
Reading symbols from /usr/lib/gconv/ISO8859-1.so...done.
Loaded symbols for /usr/lib/gconv/ISO8859-1.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_locale.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/lib-dynload/_locale.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/htmlc.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/htmlc.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/gridc.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/gridc.so
Reading symbols from /usr/lib/pango/1.1.0/modules/pango-basic-xft.so...done.
Loaded symbols for /usr/lib/pango/1.1.0/modules/pango-basic-xft.so
Reading symbols from /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/stc_c.so...done.
Loaded symbols for /ProphICy/tools/python2.3/lib/python2.3/site-packages/wxPython/stc_c.so
#0 PyEval_EvalCodeEx (co=0x406a3ae0, globals=0x835b3d0, locals=0x0, args=0x4166c1d8, argcount=2,
kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2493
2493 Py_INCREF(x);
(gdb) backtrace
#0 PyEval_EvalCodeEx (co=0x406a3ae0, globals=0x835b3d0, locals=0x0, args=0x4166c1d8, argcount=2,
kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2493
#1 0x080ec871 in function_call (func=0x41808ca4, arg=0x4166c1cc, kw=0x0) at Objects/funcobject.c:504
#2 0x0805b058 in PyObject_Call (func=0x0, arg=0x4166c1cc, kw=0x0) at Objects/abstract.c:1755
#3 0x080610f0 in instancemethod_call (func=0x41808ca4, arg=0x4166c1cc, kw=0x0)
at Objects/classobject.c:2432
#4 0x0805b058 in PyObject_Call (func=0x0, arg=0x406a136c, kw=0x0) at Objects/abstract.c:1755
#5 0x080a4307 in PyEval_CallObjectWithKeywords (func=0x418037d4, arg=0x406a136c, kw=0x0)
at Python/ceval.c:3346
#6 0x40825cc7 in wxPyCallback::EventThunker(wxEvent&) (this=0x841a4d0, event=@0x406a136c)
at src/helpers.cpp:1246
#7 0x40cc23b2 in wxEvtHandler::SearchDynamicEventTable(wxEvent&) ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#8 0x40cc1e99 in wxEvtHandler::ProcessEvent(wxEvent&) ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#9 0x40c2cc52 in wxApp::SendIdleEvents(wxWindow*) ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#10 0x40c2cb90 in wxApp::SendIdleEvents() ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#11 0x40c2cb3f in wxApp::OnIdle(wxIdleEvent&) ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#12 0x40cc212a in wxEvtHandler::SearchEventTable(wxEventTable&, wxEvent&) ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#13 0x40cc1edb in wxEvtHandler::ProcessEvent(wxEvent&) ()
from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#14 0x40c2cab1 in wxApp::ProcessIdle() () from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#15 0x40c2c3af in wxapp_idle_callback () from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#16 0x412f2c83 in g_idle_dispatch () from /usr/lib/libglib-2.0.so.0
#17 0x412eff65 in g_main_dispatch () from /usr/lib/libglib-2.0.so.0
#18 0x412f0f98 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#19 0x412f12ad in g_main_context_iterate () from /usr/lib/libglib-2.0.so.0
#20 0x412f1a1f in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#21 0x4102939f in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
#22 0x40c2cce2 in wxApp::MainLoop() () from /ProphICy/tools/wxPython2.4.1.2/lib/libwx_gtk2d-2.4.so
#23 0x40822f23 in wxPyApp::MainLoop() (this=0x83fc1b0) at src/helpers.cpp:131
#24 0x4082c546 in _wrap_wxPyApp_MainLoop (self=0x0, args=0x406a134c, kwargs=0x406a2714)
at src/gtk/wx.cpp:1383
#25 0x080ecc78 in PyCFunction_Call (func=0x4069ea0c, arg=0x406a134c, kw=0x2)
at Objects/methodobject.c:108
#26 0x0805b058 in PyObject_Call (func=0x822f8d8, arg=0x406a134c, kw=0x406a2714)
at Objects/abstract.c:1755
#27 0x080a49d9 in ext_do_call (func=0x4069ea0c, pp_stack=0xbfffd07c, flags=1, na=1, nk=0)
at Python/ceval.c:3713
#28 0x080a2e76 in eval_frame (f=0x8229c6c) at Python/ceval.c:2151
#29 0x080a357a in PyEval_EvalCodeEx (co=0x4062fda0, globals=0x406a134c, locals=0x0, args=0x406a1318,
argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2663
#30 0x080ec871 in function_call (func=0x4164f1ec, arg=0x406a130c, kw=0x0) at Objects/funcobject.c:504
#31 0x0805b058 in PyObject_Call (func=0x822f8d8, arg=0x406a130c, kw=0x0) at Objects/abstract.c:1755
#32 0x080610f0 in instancemethod_call (func=0x4164f1ec, arg=0x406a130c, kw=0x0)
at Objects/classobject.c:2432
#33 0x0805b058 in PyObject_Call (func=0x822f8d8, arg=0x406a130c, kw=0x0) at Objects/abstract.c:1755
#34 0x080a4743 in do_call (func=0x417ed93c, pp_stack=0xbfffd4ac, na=1, nk=1080693516)
at Python/ceval.c:3644
#35 0x080a43ef in call_function (pp_stack=0xbfffd4ac, oparg=1080693516) at Python/ceval.c:3460
#36 0x080a2a48 in eval_frame (f=0x819eca4) at Python/ceval.c:2116
#37 0x080a467d in fast_function (func=0x2, pp_stack=0xbfffd5dc, n=1, na=1, nk=0)
at Python/ceval.c:3518
#38 0x080a445f in call_function (pp_stack=0xbfffd5dc, oparg=1080693516) at Python/ceval.c:3458
#39 0x080a2a48 in eval_frame (f=0x815a9a4) at Python/ceval.c:2116
#40 0x080a357a in PyEval_EvalCodeEx (co=0x4042ce20, globals=0x406a130c, locals=0x0, args=0x815aaf0,
argcount=1, kws=0x81939d4, kwcount=1, defs=0x404d96f8, defcount=1, closure=0x0)
at Python/ceval.c:2663
#41 0x080a4601 in fast_function (func=0x2, pp_stack=0xbfffd77c, n=3, na=1, nk=135870932)
at Python/ceval.c:3529
#42 0x080a445f in call_function (pp_stack=0xbfffd77c, oparg=1080693516) at Python/ceval.c:3458
#43 0x080a2a48 in eval_frame (f=0x819386c) at Python/ceval.c:2116
#44 0x080a467d in fast_function (func=0x2, pp_stack=0xbfffd8ac, n=0, na=0, nk=0)
at Python/ceval.c:3518
#45 0x080a445f in call_function (pp_stack=0xbfffd8ac, oparg=1080693516) at Python/ceval.c:3458
#46 0x080a2a48 in eval_frame (f=0x812ac7c) at Python/ceval.c:2116
#47 0x080a357a in PyEval_EvalCodeEx (co=0x40196760, globals=0x406a130c, locals=0x4016f79c, args=0x0,
argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2663
#48 0x080a5b06 in PyEval_EvalCode (co=0x40196760, globals=0x4016f79c, locals=0x4016f79c)
at Python/ceval.c:537
#49 0x080caee9 in run_node (n=0x40158338, filename=0xbffff76a "runGui.py", globals=0x4016f79c,
locals=0x4016f79c, flags=0xbfffda08) at Python/pythonrun.c:1205
#50 0x080ca795 in PyRun_SimpleFileExFlags (fp=0x8128b28, filename=0xbffff76a "runGui.py", closeit=1,
flags=0xbfffda08) at Python/pythonrun.c:802
#51 0x08054c6e in Py_Main (argc=0, argv=0xbfffda84) at Modules/main.c:415
#52 0x080547e7 in main (argc=4, argv=0xbfffda84) at Modules/python.c:23
#53 0x420158f7 in __libc_start_main () from /lib/i686/libc.so.6
(gdb) quit
------------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org