esperar bash-builtin quema una CPU al 100 por ciento

16

Se produce al menos en GNU bash versión 4.3.42 x86_64 && GNU bash versión 4.3.11 x86_64

Utilizo en sleep & wait $!lugar de un simple sleeppara obtener un interrumpible sleeppor una señal (como SIGUSR1 ). Pero parece que waitbash-builtin se comporta de una manera extraña cuando ejecuta lo siguiente.

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)

Entonces, obtengo el subshell que quema una CPU al 100 por ciento.

Terminal 1:

pkill -P $(pgrep -P $$)

¿Tienes alguna idea de por qué ocurre este comportamiento?

NB : no se produce ningún problema cuando cat <(/subshell/)no está en segundo plano.


Otra forma de experimentar este comportamiento.

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)

Luego, consigue una cáscara congelada.


Una tercera forma de experimentar este comportamiento.

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)

Luego, consigue una cáscara congelada.

M89
fuente
Para depurar esto, es probable que tenga que compilar Bash a partir de las fuentes y averiguar dónde está en bucle (dividirlo con un depurador o agregar declaraciones de impresión) y por qué está en bucle.
Kaz
1
¿Extraño? No puedo reproducir esto aquí, estoy usando bash 4.3.42 (1) -release (x86_64-pc-linux-gnu). Debian 8. Kernel 4.6.1-1. Hago todas las pruebas que usted dice, pero la CPU sigue funcionando normalmente ... Estoy haciendo exactamente lo que usted dice, incluyendo el fg, y luego CTRL + C.
Luciano Andress Martini
Recuerdo haber leído que algunas cosas relacionadas con las incorporaciones y las señales cambiaron en bash4.4, tal vez esto podría verse afectado.
phk
Bash 4.4.20 corrige un problema de spinloop waitque se parece mucho a esto. Fui golpeado por eso en un bucle que generó subprocesos para siempre. Sin embargo, probé su escenario en 4.4.20 y todavía era un problema. Curiosamente, cuando adjunté un depurador en una versión que construí, pude ver que estaba dando vueltas, pero también tuvo el efecto de salir de él, y el bucle comenzaría a generar 'prueba' nuevamente. En otras palabras: adjuntar el depurador hizo que dejara de girar.
Halfgaar

Respuestas:

1

Observaciones

  • ctrl+cenvía SIGINTal proceso fg en la Terminal 1
  • por lo tanto, ejecutar kill -2 <PID>en la Terminal 2 es lo mismo que golpear ctrl+cen la Terminal 1
  • haciendo uno de los dos puntos anteriores antes de ejecutar kill -10 <PID>en la Terminal 2 maneja SIGINTcorrectamente
  • hacerlo después de ejecutar kill -10 <PID>en la Terminal 2 (enviar señal SIGUSR1) no se maneja SIGINTcorrectamente y conduce al comportamiento problemático
  • Reemplazar kill -2 <PID>en la Terminal 2 ( SIGINT) con kill -15 <PID>( SIGTERM) o kill -9 <PID>( SIGKILL) conduce siempre para corregir el manejo de la señal.
  • la ejecución kill -10 <PID>en la Terminal 2 interrumpe la waitconstrucción pero no abandona el bucle ya que testse imprime inmediatamente después de que la señal SIGUSR1queda atrapada y el bucle continúa.
  • El envío SIGINTsale del bucle de ejecución y congela el shell o nunca se interrumpe waity permanece esperando / congelado.

Conclusión

SIGINTno se busca y maneja correctamente o se ignora después de la captura manual SIGUSR1o tal vez cualquier otra captura definida por el usuario. Eso significa que el proceso aún existe y es por eso que consume / calienta la CPU o congela el shell. Ejecutar kill -15 <PID>o kill -9 <PID>desde la Terminal 2 finaliza / mata el proceso y le devuelve el control sobre la Terminal 1 y relaja su CPU.

Por qué ocurre este problema, sigue siendo un misterio, pero espero que alguien pueda explicar exactamente lo que realmente está sucediendo detrás de las cortinas.

Neni
fuente