Arrêter une boucle infinie

Lorsque l’on écrit ses premiers programmes en C, on fait parfois des erreurs qui font que le programme que l’on exécute ne se termine jamais. Considérons l’exemple ci-dessous:

#include <stdio.h>

int main(int arg, char **argv) {
  printf("Start \n");
  int i=3;
  while(1) {
    i+=i;
  }
  printf("End \n");
}

Une fois compilé, ce programme va s’exécuter sans jamais s’arrêter.

# ./montest
Start 

La solution standard pour terminer ce programme est de l’arrêter en tapant sur les touches Ctrl et C. Techniquement, cela force l’envoi d’un signal SIGINT par le shell au processus qui s’exécute.

Certains programmes (pas cet exemple simple) peuvent intercepter ce signal et l’ignorer. Dans ce cas, une solution est de mettre le programme en tâche de fond (en tapant sur Ctrl et Z).

# ./montest
Start 
^Z
[2]+  Stopped                 ./montest

Un shell tel que bash(1) contient de nombreuses fonctionnalités qui permettent de contrôler les programmes mis en tâche de fond. Elles sont décrites dans la section JOB CONTROL de bash(1).

Un autre utilitaire intéressant est ps(1). Il permet de consulter le contenu de la table des processus, c’est-à-dire de lister les programmes qui sont en cours d’exécution. Lors de notre essai, 4 programmes s’exécutaient:

# ps
  PID TTY          TIME CMD
 2433 pts/0    00:00:03 emacs
 3794 pts/0    00:00:00 bash
 5213 pts/0    00:00:00 montest
 5216 pts/0    00:00:00 ps

Le premier, emacs est l’éditeur dans lequel le programme C de test a été écrit. Le second est le shell courant. Le troisième le programme qui boucle et le dernier l’utilitaire ps lui-même.

Pour forcer la terminaison du programme montest, il suffit de lui envoyer le signal SIGKILL` avec la commande kill(1).

# kill -SIGKILL 5213
# ps
  PID TTY          TIME CMD
 2433 pts/0    00:00:03 emacs
 3794 pts/0    00:00:00 bash
 5456 pts/0    00:00:00 ps
[2]+  Killed                  ./montest
Ecrit le April 6, 2020