PySide app seems to ignore SIGTERM during shutdown when run at startup using ~/.config/autostart
-
My PySide app seems to ignore the TERM signal sent during shutdown on Linux when it is automatically started by putting an entry in ~/.config/autostart.
I came to the conclusion that the issue is with PySide/Qt through the following experiment.
First, I created a simple Python script that catches the TERM signal and prints a confirmation then exits. Here is the code.
@import signal
import sys
import timedef on_quit(*args):
print 'here', args
sys.exit(0)for i in [x for x in dir(signal) if x.startswith('SIG')]:
try:
signum = getattr(signal, i)
if i == 'SIGCHILD' or i == 'SIGCHLD':
continue
signal.signal(signum, on_quit)
except Exception, m:
print 'Skipping %s' % itime.sleep(1000000)@
The for loop just registers the on_quit method on all possible signals.
Calling this in a terminal and sending it the TERM signal by killing it, I can confirm that it is being caught and processed by the script.
I then tried to run this script at startup by including an entry in ~/.config/autostart. The entry is similar to the following:
@[Desktop Entry]
Version=1.0
Type=Application
Name=Test
GenericName=Test
Comment=Test
Exec=strace -T -f -tt -o run_test.strace run_test
Terminal=false
StartupNotify=false@I used strace to trace the system calls of the script to confirm in another way that it is catching the TERM signal. The options to strace tells it to include the time spent on the system call, to follow forks, to print the time of day with microseconds, and to send the output to run_test.strace, in that order.
run_test is just a bash script that calls the Python script; it is included because that is how my original PySide app is being called. The code for it is:
@#!/bin/bash
python test.py &>out.test@I proceeded to test it by adding the desktop entry to ~/.config/autostart, restarting the computer, then shutting it down. run_test.strace contained the line "--- SIGTERM (Terminated) ... ---" which confirms that SIGTERM was sent and caught. out.test also contains the expected output which further confirms it.
I then tried to test a simple PySide application with signal handling. The code is as follows.
@import signal
import sys
import time
from PySide.QtGui import QApplication
from PySide.QtCore import QTimerapp = QApplication([])
timer = QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)def on_quit(*args):
print 'here', args
sys.exit(0)for i in [x for x in dir(signal) if x.startswith('SIG')]:
try:
signum = getattr(signal, i)
if i == 'SIGCHILD' or i == 'SIGCHLD':
continue
signal.signal(signum, on_quit)
except Exception, m:
print 'Skipping %s' % iapp.exec_()@
The QTimer is essential to allow the signal handler to execute.
Running the above script in a terminal and sending it the TERM signal, the output still confirms that the TERM signal is being caught and processed. Running it through strace also shows the line "--- SIGTERM (Terminated) ... ---".
When running it during startup, however, the output shows that the on_quit method is not called nor is there an indication in the strace output that it was sent the TERM signal.
Could anyone help? I can provide the strace outputs if needed. System is Ubuntu 12.04 32bit.
Further experimentation shows that it happens with QApplication but not with QCoreApplication. It's something probably GUI related then?