Newsgroup: it.comp.os.linux.development
Titolo: SIGSEGV e SIGBUS multipli

Ciao a tutti,
    ho bisogno di "provare" a fare dell'I/O fisico (per verificare il 
funzionamento di un mmap). Questo puo` fallire con SIGBUS o SIGSEGV (dipende da 
dove faccio l'I/O). Nessun problema, faccio un signal() e tutto a posto. Giusto? 
Sbagliato! Funge solo la prima volta e non la seconda. Ecco un sunto della parte 
del codice che gestisce i segnali:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf env;
void sigH( int sigNum ) {
   if ( signal( sigNum, sigH ) == SIG_ERR )
     perror( "Signal re-set" );
   longjmp( env, 1 );
}
int main() {
   int *ptr = NULL;
   if ( signal( SIGSEGV, sigH ) == SIG_ERR )
     perror( "Signal set" );
   printf( "First\n" ); fflush( stdout );
   if ( setjmp( env ) == 0 ) *ptr = 0;
   printf( "Second\n" ); fflush( stdout );
   if ( setjmp( env ) == 0 ) *ptr = 0;
   printf( "Done\n" );
   exit( 0 );
}
Se provate il codice di cui sopra, il signal funge la prima volta e non la 
seconda (sulla mia macchina il programma crash-a con un bel SIGSEGV).
Ho anche provato a ripetere il signal() prima del *ptr = 0, nulla.
Senza il setjmp/longjmp il programma entra in loop sul *ptr = 0.
Chi mi trova l'errore? O una scappatoia (per esempio come convincere il 
programma a non ripetere il *ptr = 0 in caso di un SIGSEGV/SIGBUS cosi` da 
ecitare il setjmp/longjmp)?
Grazie in anticipo,
-- 
        Roberto Divia`              Love at first sight is one of the greatest
Dep:PH Bat:53 Mailbox:C02110      labour-saving devices the world has ever seen
Route de Meyrin 385               ---------------------------------------------
Case Postale                                Phone:  
+41-22-767-4994
CH-1211 Geneve 23 CERN                      Fax:    
+41-22-767-9585
Switzerland                                 E-Mail: 
Robert...@cern.ch

 ecitare il setjmp/longjmp)?
confermo tutti i tuoi dubbi, purtroppo sono praticamente a zero di
setjmp/longjmp. Comunque sembra che l'handler nn esista piu' dopo il
primo SIGSEGV. Non c'č modo di evitare l'utilizzo di setjmp/longjmp?
anche perchč dal man:"longjmp() and siglongjmp() make programs hard to
understand and maintain.  If possible an alternative should be used"


Non trovo soluzioni alternative, purtroppo.
Forse con un fork()...
Ciao,


 [...]
Ciao  Manlio Perillo


Ciao Manlio,
    gia` provato, non funge :-(
    Ho risolto il problema. Ho visto con una serie di printf che il signal 
handler non veniva chiamato del tutto al secondo "*ptr". Allora ho pensato che 
il segnale fosse stato bloccato ed in effetti e` quel che succede. Ho risolto il 
tutto usando sigaction() col flag SA_NODEFER invece di usare signal(). Cosi` il 
signal handler viene chiamato col segnale abilitato e va tutto a posto. Penso 
che signal() non ri-abilita il segnale in questione se viene chiamato 
all'interno di un signal handler. Mi puzza di baco. In ogni caso, problema 
risolto :-)
Ciao,


 risolto :-)
secondo me no, saebbe un po' troppo palese ed evidente come bug, ma non mi
pronuncio oltre visto che non conosco longjmp/setjmp

 pronuncio oltre visto che non conosco longjmp/setjmp
Ho informato qualche altro newgroup, vediamo che ne salta fuori ;-)


 Ho informato qualche altro newgroup, vediamo che ne salta fuori ;-)
aggiornaci :)

 aggiornaci :)
Non ne salta fuori niente, dicono che e` da aspettarselo dato che setjmp/longjmp 
sono considerate unsafe se chiamate in un signal handler. Il fatto che ci siano 
dozzine di riferimenti in rete a questa procedura non li tocca. Boh...
