Domanda

Sto riscontrando un errore un po' strano mentre eseguo Perl in un ambiente chroot su Solaris 9 (Sparc).Noi Sono utilizzando un Perl personalizzato, ma è quasi esattamente Perl 5.8.7 e questa versione è in esecuzione da anni su varie piattaforme incluso Solaris 8-10.

Il codice seguente è piuttosto semplice:

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

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

Tuttavia, se eseguo questo, "Mi sono appena svegliato!" non viene mai stampato - invece, il programma termina e "Sveglia" viene riecheggiato sullo schermo.Questo succede solo se c'è una pausa: se scrivo un programma che fa molti calcoli e impiega 10 secondi per essere eseguito, tutto funziona bene.Succede anche solo in un ambiente chroot.

Ho scaricato %SIG, che ha una voce 'ALRM => undef', come previsto: l'ambiente non chroot ha lo stesso comportamento.Tuttavia, se cambio lo script per includere:

$SIG{ALRM} = sub {};

...tutto funziona bene.Allora, qual è il problema?Non ho molta esperienza con Solaris, ma deve esserci un modo per far sì che i gestori di segnale predefiniti si comportino correttamente.

È stato utile?

Soluzione

La prima cosa che mi piacerebbe provare è quello di eseguire il programma di esempio sotto capriata:

truss testprogram.pl

Questo mostrerà le chiamate di sistema effettivi utilizzati per implementare il sonno. Su un sistema Solaris 8 che ho accesso, la parte rilevante della produzione è:

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

In un host Solaris 10, essa stampa:

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

Immagino si otterrà qualcosa di più vicino all'uscita Solaris 8, ed è probabilmente mostro il sigaction () chiamata per un motivo qualsiasi.

Al di là di questo, mi piacerebbe verificare che le librerie condivise all'interno del chroot / usr / lib sono in realtà le versioni corrette per l'host e la versione del sistema operativo. L'uscita capriata mostrerà anche esattamente quali hanno condiviso le librerie vengono caricati da perl.

Altri suggerimenti

Consiglio semplicemente di sostituire il sleep 1 chiama con select(undef, undef, undef, 1) ed evitare l'intera questione.

Dai sintomi che fornisci, scommetto che il tuo script Perl chroot è in fase di implementazione sleep in termini di SIGALRM (come consentito da POSIX), e che per qualche ragione perl non cattura il segnale come dovrebbe, forse perché non si aspetta tale implementazione.È la tua build personalizzata di Perl?È un'idiosincrasia nel chroot'd libc?Fa perl -e "sleep 1" sotto chroot mostra lo stesso problema?Eccetera.Eccetera.Difficile dirlo senza l'accesso all'ambiente e uno strumento simile capriata.

Ancora una volta, l’intero problema può essere evitato: select non giocherà con SIGALRM.

Hai ancora la versione di Perl che viene fornito con Solaris? Se è così, allora provare il codice su di esso. Se non si dispone di quella versione, allora vi consiglio di scaricare Perl 5.8.7 , la compilazione di una versione magazzino, e quindi testare lo script su di esso.

Se lo script viene eseguito correttamente, in una di queste due versioni, poi si sa il problema è legato ai cambiamenti nella vostra versione di Perl. Se lo script ha lo stesso errore, quindi poi vorrei suggerire il download di Perl 5.8.9 , compilarlo, e quindi il controllo per vedere se il bug va via. Se non lo fa, allora, complimenti, avete trovato un bug in Perl. Probabilmente si desidera eseguire perlbug di segnalarlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top