Comment puis-je intercepter un programme qui renvoie 139 (défaut de segmentation) dans bash?

10

J'ai un script bash qui teste certains programmes et l'un des programmes renvoie Segmentation faultdonc j'ai essayé d'ajouter un piège dans la tête de mon script:

trap "echo 'segfault occured!'" SIGSEGV

Cela n'a cependant rien fait. j'ai utilisé

echo $?

juste après le programme qui produit le segfault et j'obtiens 139 en sortie. Comment puis-je ajouter une interruption pour ce code d'erreur spécifique?

Pithikos
la source

Réponses:

7

trap "$instructions" SIGSEGV piège les défauts de segmentation dans la coquille elle-même.

Si vous exécutez votre script sous set -e, vous pouvez mettre un piège sur EXIT(ou 0). Il sera exécuté lorsque votre script se terminera (que ce soit à cause d'une commande renvoyant un état différent de zéro, ou en appelant explicitement exitou en tombant à la fin du script). Pour tester un défaut de segmentation, vérifiez l' $?entrée dans le piège. (Notez que cela $?pourrait être 139 car le programme est revenu normalement avec le statut 139; cela peut être évité si vous effectuez votre traitement dans le shell.)

set -e
trap 'case $? in
        139) echo "segfault occurred";;
      esac' EXIT

Dans bash ou ksh ou zsh, vous n'avez pas besoin d'utiliser set -epour exécuter un trap après chaque commande qui retourne un statut différent de zéro, vous pouvez mettre un trap à la ERRplace. Comme précédemment, vous devez vérifier l' $?entrée dans le piège et 139 peut (mais rarement) signifie que le programme a renvoyé ce statut.

Gilles 'SO- arrête d'être méchant'
la source
6

De man bash:

   trap [-lp] [[arg] sigspec ...]
          The command arg is to  be  read  and  executed  when  the  shell
          receives  signal(s)  sigspec.

Lorsque votre programme se sépare, votre bash obtient juste un SIGCHLDparce qu'un enfant est sorti (de quelque manière que ce soit).

Vous pouvez cependant utiliser le code de sortie, stocké dans $?, dans certains conditionnels, et le trap SIGCHLD:

trap 'if [[ $? -eq 139 ]]; then echo "segfault !"; fi' CHLD

Notez que cela set -bmpourrait être nécessaire si cela (ce qu'il fait probablement) est utilisé dans un bash non interactif (tel qu'un script).

Edit: Voir aussi cette réponse (de Gilles) sur un problème similaire en utilisant bashet trap.

sr_
la source
Quelque chose de bizarre se produit. J'utilise un piège trap "echo 'something happened!'" {1..64}et je ne reçois toujours rien. J'ai même essayé avec set -bmet set -o monitormais nada.
Pithikos
Avez-vous essayé cela de manière interactive? trap "echo 'something happened'" {1..31}fonctionne pour moi (en laissant de côté les !spécifications de signal qui y conduisent bash: trap: XX: invalid signal specification).
sr_