GNOME Bugzilla – Bug 698623
unable to trap SIGINT
Last modified: 2017-12-04 15:21:08 UTC
Created attachment 242181 [details]
minimal example to demonstrate the bug
I'm using Arch Liunx, today after an update from python-gobject 3.4.2 to 3.8.1 the attached example code is unable to trap SIGINT.
Instead of terminating normally it crashes with following error:
^CTraceback (most recent call last):
raise KeyboardInterrupt KeyboardInterrupt
The issue is the GLib override for MainLoop ends up using GLib.unix_signal_add_full to set a SIGINT to exit the loop. This clobbers anything set with Python signals, probably because both APIs use the same underlying unix API. The library probably shouldn't have a side affects like this and it is also causing other problems (bug 695683).
One solution might be to detect if anything is already set on the Python signal side of things and not touch it if there is.
I have a bug which is slightly different, but I think solving one will be 90% of solving the other, so I'll put it here.
GLib.MainLoop() doesn't restore the existing Python signal handlers (and the signal module is entirely unaware of the snafu GLib does): see attached program for how this breaks.
If you're thinking that code is a bit silly, it is, but the original program ran a main loop, and then did stuff afterwards without GLib which then didn't handle SIGINT correctly (context: https://github.com/wardi/urwid/issues/77).
As a side note, I'm a bit surprised the signal handling in overrides/GLib.py is done in __init__ and __del__, rather than being at the top&bottom of the run() override (given the lack of guarantees about when __del__ is run).
Created attachment 302361 [details]
minimal program to show SIGINT not being restored
In attempting to write a test for this, I discovered that the use of __del__ means MainLoop objects can never be freed: the unix signal source has a reference to the _handler function, which has a reference to the MainLoop object, and as the source won't be removed until the MainLoop is deleted...
Created attachment 302413 [details] [review]
patch to fix all the things
Here's a patch which fixes all the issues in this bug, I think.
The patch still seems to have a few debug print statements in it.
See a proposed patch at https://bugzilla.gnome.org/show_bug.cgi?id=622084#c35 which would also fix the problems mentioned here.
This is fixed in master now.
GLib.MainLoop.run() will only set up a signal handler in case none was set up before (be it through glib or python) and will remove the signal handler once run() returns control.
In case this breaks any existing code please speak up and we can look into providing a more backwards compatible approach, depending on the issue.