Como posso interceptar um programa que retorna 139 (falha de segmentação) no bash?

10

Eu tenho um script bash que testa alguns programas e um dos programas retorna, Segmentation faultentão tentei adicionar uma armadilha na cabeça do meu script:

trap "echo 'segfault occured!'" SIGSEGV

Isso, no entanto, não fez nada. eu usei

echo $?

logo após o programa que produz o segfault e recebo 139 como saída. Como posso adicionar uma interceptação para esse código de erro específico?

Pithikos
fonte

Respostas:

7

trap "$instructions" SIGSEGV detecta falhas de segmentação no próprio shell.

Se você executar seu script em set -e, poderá colocar uma armadilha em EXIT(ou 0). Ele será executado quando o script terminar (seja devido a um comando que retorna um status diferente de zero, seja por uma chamada explícita exitou por uma queda no final do script). Para testar uma falha de segmentação, verifique $?a entrada na armadilha. (Observe que $?pode ser 139 porque o programa retornou normalmente com o status 139; isso é evitável se você processar seu shell.)

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

No bash ou ksh ou zsh, você não precisa set -eexecutar uma interceptação após cada comando que retorna um status diferente de zero, você pode colocar uma interceptação ERR. Como antes, você precisa verificar $?a entrada na armadilha e 139 pode (mas raramente o faz) significar que o programa retornou esse status.

Gilles 'SO- parar de ser mau'
fonte
6

De man bash:

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

Quando o programa é segmentado por falhas, o bash recebe um SIGCHLDporque algum filho saiu (de qualquer maneira).

Você pode, no entanto, usar o código de saída, armazenado em $?, em algumas condições, e interceptar SIGCHLD:

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

Observe que set -bmpode ser necessário se isso (o que provavelmente faz) for usado em um bash não interativo (como um script).

Edit: Veja também esta resposta (de Gilles) sobre um problema semelhante usando bashe trap.

sr_
fonte
Algo estranho acontece. Eu uso armadilha trap "echo 'something happened!'" {1..64}e ainda não recebo nada. Eu até tryied com set -bme set -o monitormas nada.
Pithikos
Você já tentou isso de forma interativa? trap "echo 'something happened'" {1..31}funciona para mim (deixando de fora as !especificações de sinal e as que levam a bash: trap: XX: invalid signal specification).
sr_