¿Cómo puedo atrapar un programa que devuelve 139 (falla de segmentación) en bash?

10

Tengo un script bash que prueba algunos programas y uno de los programas regresa, Segmentation faultasí que traté de agregar una trampa en la cabeza de mi script:

trap "echo 'segfault occured!'" SIGSEGV

Eso sin embargo no hizo nada. solía

echo $?

justo después del programa que produce el segfault y obtengo 139 como salida. ¿Cómo puedo agregar una trampa para ese código de error específico?

Pithikos
fuente

Respuestas:

7

trap "$instructions" SIGSEGV atrapa las fallas de segmentación en el propio shell.

Si ejecuta su script debajo set -e, puede poner una trampa en EXIT(o 0). Se ejecutará cuando finalice su secuencia de comandos (ya sea debido a que un comando devuelve un estado distinto de cero, o llamando explícitamente exito cayendo al final de la secuencia de comandos). Para probar una falla de segmentación, verifique la $?entrada a la trampa. (Tenga en cuenta que $?podría ser 139 porque el programa regresó normalmente con el estado 139; esto se puede evitar si realiza el procesamiento en el shell).

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

En bash o ksh o zsh, no necesita usar set -epara ejecutar una trampa después de cada comando que devuelve un estado distinto de cero, en su lugar, puede poner una trampa ERR. Como antes, debe verificar la $?entrada a la trampa, y 139 puede (pero rara vez lo hace) significar que el programa devolvió este estado.

Gilles 'SO- deja de ser malvado'
fuente
6

De man bash:

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

Cuando su programa falla, su bash solo obtiene un SIGCHLDporque algún niño salió (de cualquier manera).

Sin embargo, puede usar el código de salida, almacenado $?, en algunos condicionales y trap SIGCHLD:

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

Tenga en cuenta que set -bmpodría ser necesario si esto (lo que probablemente hace) se usa en un bash no interactivo (como un script).

Editar: Vea también esta respuesta (de Gilles) sobre un problema similar usando bashy trap.

sr_
fuente
Algo raro sucede. Yo uso trampa trap "echo 'something happened!'" {1..64}y todavía no consigo nada. Incluso intenté con set -bmy set -o monitorpero nada.
Pithikos
¿Has probado esto de forma interactiva? trap "echo 'something happened'" {1..31}funciona para mí (omitiendo !las especificaciones de señal y esas que conducen a bash: trap: XX: invalid signal specification).
Sr_