Quelle est la différence entre Ctrl-C et SIGINT?
J'ai débogué un programme Python qui segfaults après avoir reçu une exception KeyboardInterrupt
. Cela se fait normalement en appuyant sur Ctrl + C depuis le shell. Pour tester si un changement de code particulier a corrigé le bug, j'ai eu un petit script shell qui a envoyé SIGINT
au programme au hasard après le démarrage. Le problème que j'ai est que l'envoi de Ctrl + C semble avoir un effet différent sur le programme que l'envoi du signal SIGINT
et ne provoque donc pas l'apparition du bug, donc je je me demande Quelle est la différence entre les deux actions.
Le programme n'attrape aucune action du clavier, et n'est qu'un programme python avec quelques threads / processus. Il n'installe aucun gestionnaire de signal (bien que Python le fasse), et stty -a
donne intr = ^C
. Je soupçonne que Ctrl + C envoie SIGINT
à tous les sous-processus/threads tandis que kill -INT
envoie seulement au processus principal, mais c'est aussi loin que mes soupçons vont.
Voici le script shell qui envoie le kill -INT
.
wait
while :; do
seconds="$(python -c 'import random; print random.random()*4')"
./mandos --debug --configdir=confdir
--statedir=statedir --no-restore --no-dbus &
pid=$!
{ sleep $seconds; kill -INT $pid; } &
fg %./mandos
status=$?
if [ $status -gt 1 ]; then
echo "Failed exit $status after $seconds seconds"
break
fi
wait
done
2 réponses
^C
envoie un SIGINT
pour tous les processus du groupe de processus au premier plan. Pour faire l'équivalent avec kill
, vous devez envoyer le signal au groupe de processus (concept au niveau du système D'EXPLOITATION):
kill -SIGINT -<pid>
Ou au travail (concept au niveau du shell, le pipeline s'est terminé par &
):
kill -SIGINT %
Comme décrit ici :
Python installe un petit nombre de gestionnaires de signaux par défaut: SIGPIPE est ignoré (donc les erreurs d'écriture sur les tuyaux et les sockets peuvent être signalées comme exceptions Python ordinaires) et SIGINT est traduit en un Keyboardinterrupt exception. Tous ces éléments peuvent être remplacées.
Ainsi, le comportement devrait être le même entre l'envoi d'un SIGINT et un Ctrl + c.
Mais, vous devez être prudent avec les KeyboardInterrupt
, si quelque part dans votre code, vous avez un
try:
...
except: # notice the lack of exception class
pass
Cela va "manger" L'exception KeyboardInterrupt.