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.


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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.