Pregunta

Estoy corriendo en un poco de un error extraño durante la ejecución de Perl en un entorno chroot en Solaris 9 (SPARC). We son utilizando una costumbre Perl, pero es casi exactamente Perl 5.8.7, y esta versión ha estado funcionando durante años en diversas plataformas, incluyendo Solaris 8-10.

El siguiente código es bastante sencillo:

#!/usr/bin/perl
use strict; 
use warnings;

print "About to sleep(1)\n";
sleep 1;
print "Just woke up!\n";

Sin embargo, si se me acaba de eso, "acaba de despertar!" Nunca se imprime - en su lugar, el programa termina y "Alarma" se hizo eco a la pantalla. Esto sólo ocurre si hay un sueño - si escribo un programa que hace un montón de matemáticas y tarda 10 segundos para correr, todo funciona bien. También sólo ocurre en un entorno chroot.

He vertido% SIG, que tiene una entrada de 'ALRM => undef', que se espera - el entorno no chroot tiene el mismo comportamiento. Sin embargo, si cambio de la secuencia de comandos para incluir:

$SIG{ALRM} = sub {};

... todo funciona bien. Así que, ¿cuál es el problema? No tengo mucha experiencia con Solaris, pero no tiene que ser una manera de hacer que los gestores de señales por defecto se comportan adecuadamente.

¿Fue útil?

Solución

Lo primero que iba a tratar es ejecutar el programa muestra bajo cercha:

truss testprogram.pl

Esto mostrará las llamadas al sistema reales utilizados para implementar el sueño. En un sistema Solaris 8 que tengo acceso a la parte pertinente de la salida es:

write(1, " A b o u t   t o   s l e".., 18)      = 18
time()                                          = 1247258429
alarm(0)                                        = 0
sigaction(SIGALRM, 0xFFBEF6E0, 0xFFBEF790)      = 0
sigfillset(0xFF0C28D0)                          = 0
sigprocmask(SIG_BLOCK, 0xFFBEF780, 0xFFBEF770)  = 0
alarm(1)                                        = 0
    Received signal #14, SIGALRM, in sigsuspend() [caught]
sigsuspend(0xFFBEF760)                          Err#4 EINTR
setcontext(0xFFBEF448)
alarm(0)                                        = 0
sigprocmask(SIG_UNBLOCK, 0xFFBEF780, 0x00000000) = 0
sigaction(SIGALRM, 0xFFBEF6E0, 0x00000000)      = 0
time()                                          = 1247258430
Just woke up!
write(1, " J u s t   w o k e   u p".., 14)      = 14

En un host de Solaris 10, se da salida:

write(1, " A b o u t   t o   s l e".., 18)      = 18
time()                                          = 1247258270
nanosleep(0xFFBFF770, 0xFFBFF768)               = 0
time()                                          = 1247258271
Just woke up!
write(1, " J u s t   w o k e   u p".., 14)      = 14

Me imagino que obtendrá algo más cercano a la salida de Solaris 8, y probablemente voy a mostrar el sigaction () llame a fallar por alguna razón.

Más allá de eso, me gustaría comprobar que las bibliotecas compartidas dentro del chroot / usr / lib son en realidad las versiones correctas para el anfitrión y versión del sistema operativo. La salida del braguero también le mostrará exactamente qué bibliotecas compartidas están siendo cargadas por el Perl.

Otros consejos

Yo recomiendo la simple sustitución de las llamadas sleep 1 con select(undef, undef, undef, 1) y evitando todo el tema.

A partir de los síntomas que facilite, se apostaría que su script de perl chroot'd está implementando sleep en términos de SIGALRM (como lo permita POSIX), y que por alguna razón Perl no es la captura de esa señal como debe ser, quizás porque no está a la espera de que la aplicación. ¿Es su estructura de encargo de Perl? Es una idiosincrasia en el libc chroot'd? No perl -e "sleep 1" bajo chroot muestran el mismo problema? Etc., etc. Es difícil de decir sin acceso al medio ambiente y una herramienta como armadura .

Una vez más, todo el problema puede ser evitado: select no ensuciar con SIGALRM

.

¿Todavía no tienen la versión de Perl que viene con Solaris? Si es así, entonces probar su código en él. Si no tiene esta versión, entonces le sugiero descargar Perl 5.8.7 , compilar una versión de valores y, a continuación, las pruebas de su escritura en él.

Si la secuencia de comandos se ejecuta correctamente, en cualquiera de las dos versiones, entonces usted sabe que el problema está relacionado con los cambios en su versión de Perl. Si el script tiene el mismo error, entonces sugeriría la descarga Perl 5.8.9 , compilación, y luego la comprobación para ver si el error desaparece. Si no lo hace, entonces, felicitaciones, usted ha encontrado un fallo en Perl. Es probable que desee ejecutar perlbug para informar de ello.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top