tunggu bash-builtin membakar CPU pada 100 persen


16

Terjadi setidaknya pada GNB bash versi 4.3.42 x86_64 && GNU bash versi 4.3.11 x86_64

Saya menggunakan sleep & wait $!bukannya sederhana sleepuntuk mendapatkan interupsi sleepoleh sinyal (seperti SIGUSR1 ). Tetapi tampaknya waitbash-builtin berperilaku aneh ketika Anda menjalankan yang berikut.

Terminal 1:

cat <(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
   )&

Terminal 2:

kill -10 /the pid of the subshell, printed by the previous command/

Terminal 1:

^C (ctrl + C)

Lalu, saya mendapatkan subkulit yang membakar CPU pada 100 persen.

Terminal 1:

pkill -P $(pgrep -P $$)

Apakah Anda tahu mengapa perilaku ini terjadi?

NB : tidak ada masalah terjadi ketika cat <(/subshell/)tidak ada di latar belakang.


Cara lain untuk mengalami perilaku ini

Terminal 1:

(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
)&

Terminal 2:

kill -10 /the pid of the subshell, printed by the previous command/

Terminal 1:

fg
^C (ctrl + C)

Lalu, dapatkan cangkang beku.


Cara ketiga untuk mengalami perilaku ini

Terminal 1:

(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
)

Terminal 2:

kill -10 /the pid of the subshell, printed by the previous command/

Terminal 1:

^C (ctrl + C)

Lalu, dapatkan cangkang beku.


Untuk men-debug ini, Anda mungkin harus membangun Bash dari sumber dan mencari tahu di mana itu adalah perulangan (pecahkan dengan debugger atau tambahkan pernyataan cetak) dan mengapa itu perulangan.
Kaz

1
Aneh? Saya tidak dapat mereproduksi ini di sini, saya menggunakan bash 4.3.42 (1) -release (x86_64-pc-linux-gnu). Debian 8. Kernel 4.6.1-1. Saya melakukan semua tes yang Anda katakan tetapi CPU masih berjalan normal ... Saya melakukan persis seperti yang Anda katakan termasuk fg, dan kemudian CTRL + C.
Luciano Andress Martini

Saya ingat pernah membaca bahwa beberapa hal yang berkaitan dengan built-in dan sinyal berubah di bash4.4, mungkin ini di sini bisa terpengaruh.
phk

Bash 4.4.20 memperbaiki masalah spinloop waityang terlihat sangat mirip dengan ini. Saya terpukul oleh hal itu dalam satu lingkaran yang menelurkan sub-proses selamanya. Namun, saya menguji skenario Anda pada 4.4.20 dan itu masih menjadi masalah. Menariknya, ketika saya melampirkan debugger pada versi yang saya buat, saya bisa melihatnya sedang berputar, tetapi juga memiliki efek memutarnya, dan loop akan mulai menghasilkan 'tes' lagi. Dengan kata lain: melampirkan debugger membuatnya berhenti spinlooping.
Halfgaar

Jawaban:


1

Pengamatan

  • ctrl+cmengirim SIGINTke proses fg di Terminal 1
  • karenanya, mengeksekusi kill -2 <PID>di Terminal 2 sama dengan memukul ctrl+cdi Terminal 1
  • melakukan salah satu dari dua poin di atas sebelum mengeksekusi kill -10 <PID>di Terminal 2 menangani SIGINTdengan benar
  • melakukannya setelah dieksekusi kill -10 <PID>di Terminal 2 (mengirim sinyal SIGUSR1) tidak menangani SIGINTdengan benar dan mengarah ke perilaku bermasalah
  • Mengganti kill -2 <PID>Terminal 2 ( SIGINT) dengan kill -15 <PID>( SIGTERM) atau kill -9 <PID>( SIGKILL) selalu mengarah ke penanganan sinyal yang benar.
  • mengeksekusi kill -10 <PID>di Terminal 2 mengganggu waitbuiltin tetapi tidak meninggalkan loop karena testsegera dicetak setelah sinyal SIGUSR1terperangkap dan loop berlanjut.
  • Mengirim SIGINTkeluar dari loop eksekusi dan membekukan shell atau tidak pernah mengganggu waitdan tetap menunggu / beku.

Kesimpulan

SIGINTtidak ditangkap dan ditangani dengan benar atau diabaikan setelah menjebak secara manual SIGUSR1atau mungkin penjebak lain yang ditentukan pengguna. Itu berarti bahwa prosesnya masih ada dan itulah mengapa ia memakan / memanaskan CPU atau membekukan shell. Menjalankan kill -15 <PID>atau kill -9 <PID>dari Terminal 2 mengakhiri / membunuh proses dan memberi Anda kembali kendali atas Terminal 1 dan melemaskan CPU Anda.

Mengapa masalah ini terjadi, masih tetap menjadi misteri, tetapi saya harap seseorang dapat menjelaskan dengan tepat apa yang sebenarnya terjadi di balik tirai.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.