подождите, пока bash-buildin сожжет процессор на 100 процентов

16

По крайней мере, в GNU bash версии 4.3.42 x86_64 && GNU bash версии 4.3.11 x86_64

Я использую sleep & wait $!вместо простого sleepдля получения прерываемого sleepсигнала (как SIGUSR1 ). Но кажется, что waitbash-buildin ведет себя странным образом, когда вы запускаете следующее.

Терминал 1:

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

Терминал 2:

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

Терминал 1:

^C (ctrl + C)

Затем я получаю подоболочку, которая сжигает процессор на 100 процентов.

Терминал 1:

pkill -P $(pgrep -P $$)

Есть ли у вас идеи о том, почему такое поведение происходит?

NB : не возникает проблем, когда cat <(/subshell/)нет в фоновом режиме.


Еще один способ испытать это поведение

Терминал 1:

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

Терминал 2:

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

Терминал 1:

fg
^C (ctrl + C)

Затем получите замороженную раковину.


Третий способ испытать это поведение

Терминал 1:

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

Терминал 2:

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

Терминал 1:

^C (ctrl + C)

Затем получите замороженную раковину.

M89
источник
Чтобы отладить это, вам, вероятно, придется собрать Bash из исходных кодов и выяснить, где он зацикливается (разбить его с помощью отладчика или добавить операторы печати) и почему он зацикливается.
Каз
1
Странный? Я не могу воспроизвести это здесь, я использую bash 4.3.42 (1) -релиз (x86_64-pc-linux-gnu). Debian 8. Ядро 4.6.1-1. Я делаю все тесты, которые вы говорите, но процессор все еще работает нормально ... Я делаю точно так же, как вы говорите, включая fg, а затем CTRL + C.
Лучано Андресс Мартини
Я помню, как читал, что некоторые вещи, связанные со встроенными модулями и сигналами, изменились в bash4.4, возможно, это может повлиять на это.
phk
Bash 4.4.20 исправляет проблему спин-петля, waitкоторая выглядит очень похоже на это. Я был поражен этим в цикле, который порождал подпроцессы навсегда. Тем не менее, я проверил ваш сценарий на 4.4.20, и это все еще было проблемой. Интересно, что когда я прикрепил отладчик к версии, которую я построил, я мог видеть, что он зацикливался, но он также имел эффект выхода из него, и цикл снова начал выводить 'test'. Другими словами: присоединение отладчика сделало его остановленным.
Halfgaar

Ответы:

1

наблюдения

  • ctrl+cотправляет SIGINTв fg-процесс в Терминале 1
  • следовательно, выполнение kill -2 <PID>в терминале 2 такое же, как выполнение ctrl+cв терминале 1
  • выполнение одного из двух вышеупомянутых пунктов перед выполнением kill -10 <PID>в терминале 2 SIGINTправильно обрабатывает
  • выполнение этого после выполнения kill -10 <PID>в Терминале 2 (отправка сигнала SIGUSR1) не обрабатывается SIGINTправильно и приводит к проблемному поведению
  • Замена kill -2 <PID>в клемме 2 ( SIGINT) на kill -15 <PID>( SIGTERM) или kill -9 <PID>( SIGKILL) всегда приводит к правильной обработке сигнала.
  • выполнение kill -10 <PID>в терминале 2 прерывает waitвстроенную функцию, но не покидает цикл, поскольку testон немедленно выводится после захвата сигнала SIGUSR1и продолжения цикла.
  • Отправка SIGINTпрерывается из цикла выполнения и замораживает оболочку, или она никогда не прерывается waitи остается в ожидании / заморожена.

Вывод

SIGINTне обрабатывается и не обрабатывается правильно, или игнорируется после ручного перехвата SIGUSR1или, возможно, любого другого пользовательского перехвата. Это означает, что процесс все еще существует, и поэтому он ест / нагревает процессор или замораживает оболочку. Выполнение kill -15 <PID>или kill -9 <PID>из Терминала 2 завершает / убивает процесс и возвращает вам контроль над Терминалом 1 и ослабляет ваш ЦП.

Почему эта проблема возникает, до сих пор остается загадкой, но я надеюсь, что кто-то может точно объяснить, что на самом деле происходит за кулисами.

není
источник