Jak mogę uwięzić program, który zwraca 139 (błąd segmentacji) w bash?

10

Mam skrypt bash, który testuje niektóre programy i jeden z nich zwraca, Segmentation faultwięc próbowałem dodać pułapkę w głowie mojego skryptu:

trap "echo 'segfault occured!'" SIGSEGV

To jednak nic nie zrobiło. użyłem

echo $?

zaraz po programie, który produkuje segfault i dostaję 139 jako wynik. Jak mogę dodać pułapkę dla tego konkretnego kodu błędu?

Pithikos
źródło

Odpowiedzi:

7

trap "$instructions" SIGSEGV wychwytuje błędy segmentacji w samej powłoce.

Jeśli uruchomisz skrypt set -e, możesz umieścić pułapkę na EXIT(lub 0). Zostanie on wykonany po zakończeniu skryptu (niezależnie od tego, czy polecenie zwróci status niezerowy, czy też zostanie jawnie wywołane exitlub odpadnie od końca skryptu). Aby przetestować pod kątem błędu segmentacji, sprawdź $?wejście do pułapki. (Należy pamiętać, że $?może to być 139, ponieważ program powrócił normalnie ze statusem 139; można tego uniknąć, jeśli wykonujesz przetwarzanie w powłoce).

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

W bash, ksh lub zsh nie trzeba używać set -edo wykonania pułapki po każdym poleceniu, które zwraca stan niezerowy, można ERRzamiast tego zastosować pułapkę . Tak jak poprzednio, musisz sprawdzić $?przy wejściu do pułapki, a 139 może (ale rzadko robi) oznaczać, że program zwrócił ten status.

Gilles „SO- przestań być zły”
źródło
6

Od man bash:

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

Kiedy twój program się segreguje, twoja bash po prostu dostaje, SIGCHLDponieważ jakieś dziecko wyszło (w jakikolwiek sposób).

Możesz jednak użyć kodu wyjścia, przechowywanego w $?, w niektórych warunkach warunkowych i pułapki SIGCHLD:

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

Zauważ, że set -bmmoże to być potrzebne, jeśli to (co prawdopodobnie robi) jest użyte w nieinteraktywnym bashu (takim jak skrypt).

Edycja: Zobacz także (Gilles) odpowiedź na podobny problem przy użyciu bashi trap.

sr_
źródło
Coś dziwnego się dzieje. Używam pułapki trap "echo 'something happened!'" {1..64}i wciąż nic nie dostaję. I nawet z tryied set -bmi set -o monitorale nada.
Pithikos,
Czy próbowałeś tego interaktywnie? trap "echo 'something happened'" {1..31}działa dla mnie (pomijając te !i te specyfikacje sygnałów, które prowadzą do bash: trap: XX: invalid signal specification).
sr_