Bagaimana saya bisa menjebak program yang mengembalikan 139 (kesalahan segmentasi) di bash?

10

Saya memiliki skrip bash yang menguji beberapa program dan salah satu dari program tersebut kembali Segmentation faultjadi saya mencoba menambahkan jebakan di kepala skrip saya:

trap "echo 'segfault occured!'" SIGSEGV

Namun itu tidak melakukan apa pun. Saya menggunakan

echo $?

tepat setelah program yang menghasilkan segfault dan saya mendapatkan 139 sebagai output. Bagaimana saya bisa menambahkan jebakan untuk kode kesalahan khusus itu?

Pithikos
sumber

Jawaban:

7

trap "$instructions" SIGSEGV menjebak kesalahan segmentasi di shell itu sendiri.

Jika Anda menjalankan skrip Anda di bawah set -e, Anda dapat menempatkan jebakan pada EXIT(atau 0). Ini akan dieksekusi ketika skrip Anda berakhir (apakah karena perintah mengembalikan status bukan nol, atau dengan secara eksplisit memanggil exitatau dengan jatuh dari ujung skrip). Untuk menguji kesalahan segmentasi, periksa $?masuk ke perangkap. (Catatan yang $?mungkin 139 karena program kembali normal dengan status 139; ini dapat dihindari jika Anda melakukan pemrosesan di shell.)

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

Di bash atau ksh atau zsh, Anda tidak perlu menggunakan set -euntuk menjalankan jebakan setelah setiap perintah yang mengembalikan status bukan nol, Anda dapat menempatkan jebakan pada ERR. Seperti sebelumnya, Anda perlu memeriksa $?entri yang masuk ke perangkap, dan 139 dapat (tetapi jarang) menunjukkan bahwa program mengembalikan status ini.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
6

Dari man bash:

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

Ketika program Anda segfaults, bash Anda hanya mendapatkan SIGCHLDkarena beberapa anak keluar (dengan cara apa pun).

Anda dapat, bagaimanapun, menggunakan kode keluar, disimpan di $?, dalam beberapa kondisi, dan perangkap SIGCHLD:

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

Catatan yang set -bmmungkin diperlukan jika ini (apa yang mungkin dilakukannya) digunakan dalam bash non-interaktif (seperti skrip).

Sunting: Lihat juga jawaban (Gilles ') ini pada masalah yang sama menggunakan bashdan trap.

sr_
sumber
Sesuatu yang aneh terjadi. Saya menggunakan perangkap trap "echo 'something happened!'" {1..64}dan masih tidak mendapatkan apa-apa. Aku bahkan mencoba set -bmdan dengan set -o monitortapi nada.
Pithikos
Sudahkah Anda mencoba ini secara interaktif? trap "echo 'something happened'" {1..31}bekerja untuk saya (meninggalkan !dan spesifikasi sinyal yang mengarah ke bash: trap: XX: invalid signal specification).
sr_