esperar bash-builtin queima uma CPU a 100 por cento

15

Ocorre pelo menos no GNU bash versão 4.3.42 x86_64 && GNU bash versão 4.3.11 x86_64

Eu uso em sleep & wait $!vez de um simples sleeppara obter uma interrupção sleeppor um sinal (como SIGUSR1 ). Mas parece que o waitbash-builtin se comporta de uma maneira estranha quando você executa o seguinte.

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)

Então, recebo o subshell que queima uma CPU a 100%.

Terminal 1:

pkill -P $(pgrep -P $$)

Você tem alguma idéia de por que esse comportamento ocorre?

NB : nenhum problema ocorre quando o cat <(/subshell/)não está em segundo plano.


Outra maneira de experimentar esse comportamento

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)

Então, pegue uma concha congelada.


Uma terceira maneira de experimentar esse comportamento

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)

Então, pegue uma concha congelada.

M89
fonte
Para depurar isso, você provavelmente precisará compilar o Bash a partir de fontes e descobrir onde ele está fazendo loop (interrompa-o com um depurador ou adicione instruções de impressão) e por que ele está fazendo loop.
Kaz
1
Estranho? Eu não posso reproduzir isso aqui, estou usando o bash 4.3.42 (1) -release (x86_64-pc-linux-gnu). Debian 8. Kernel 4.6.1-1. Eu faço todos os testes que você diz, mas a CPU ainda está funcionando normalmente ... Estou fazendo exatamente como você diz, incluindo o fg e, em seguida, CTRL + C.
Luciano Andress Martini
Lembro-me de ler que algumas coisas relacionadas a embutidos e sinais mudaram no bash4.4, talvez isso aqui possa ser afetado.
Phd
O Bash 4.4.20 corrige um problema de spinloop waitque se parece muito com isso. Fui atingido por isso em um loop que gerou subprocessos para sempre. No entanto, testei seu cenário na 4.4.20 e ainda era um problema. Curiosamente, quando anexei um depurador em uma versão que construí, pude ver que ele estava circulando, mas também teve o efeito de sair dele, e o loop começaria a emitir 'test' novamente. Em outras palavras: anexar o depurador fez com que ele parasse de girar.
Halfgaar 02/04/19

Respostas:

1

Observações

  • ctrl+cenvia SIGINTpara o processo fg no Terminal 1
  • portanto, executar kill -2 <PID>no Terminal 2 é o mesmo que bater ctrl+cno Terminal 1
  • executando um dos dois pontos acima antes de executar kill -10 <PID>no Terminal 2 manipula SIGINTcorretamente
  • fazê-lo após a execução kill -10 <PID>no Terminal 2 (enviando sinal SIGUSR1) não funciona SIGINTcorretamente e leva ao comportamento problemático
  • Substituir kill -2 <PID>no Terminal 2 ( SIGINT) por kill -15 <PID>( SIGTERM) ou kill -9 <PID>( SIGKILL) sempre leva a corrigir o manuseio do sinal.
  • executar kill -10 <PID>no Terminal 2 interrompe o waitbuiltin, mas não sai do loop, pois testé imediatamente impresso após o sinal SIGUSR1ser interceptado e o loop continuar.
  • O envio SIGINTinterrompe o loop em execução e congela o shell ou ele nunca interrompe waite fica esperando / congelado.

Conclusão

SIGINTnão é cought e tratado corretamente ou é ignorado após a captura manual SIGUSR1ou talvez qualquer outra captura definida pelo usuário. Isso significa que o processo ainda existe e é por isso que ele come / aquece a CPU ou congela o shell. A execução kill -15 <PID>ou kill -9 <PID>do Terminal 2 finaliza / mata o processo e devolve o controle sobre o Terminal 1 e relaxa sua CPU.

Por que esse problema ocorre, ainda permanece um mistério, mas espero que alguém possa explicar exatamente o que realmente está acontecendo por trás das cortinas.

Neni
fonte