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
24
demandé sur SamB 2011-12-06 15:02:56

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 %
14
répondu ninjalj 2011-12-06 20:30:45

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.

4
répondu Cédric Julien 2011-12-06 11:16:56