2011-03-13 14 views
5

he escrito un pequeño fragmento de código. Este código primero bloquea el {SIGSEGV}, luego agrega SIGRTMIN al mismo conjunto. Entonces, mi conjunto de señal final es {SIGSEGV, SIGRTMIN}. Por lo tanto, si uso SIG_UNBLOCK, según mi entendimiento, primero debe desbloquearse SIGRTMIN, y nuevamente si invoco SIG_UNBLOCK, SIGSEGV debe ser desbloqueado.sigprocmask() señales de bloqueo en UNIX

Es decir, 1) {SIGSEGV, SIGRTMIN} 2) SIG_UNBLOCK = desbloquear SIGRTMIN, 3) Invocar nuevamente SIG_UNBLOCK = desbloquear SIGSEGV. Le estoy dando al proceso un SIGRTMIN solamente, por lo tanto, mi segundo desbloqueo debe detener el proceso con SIGRTMIN. Pero no lo es. Por favor ayuda. N.B: No proporcione enlaces a las respuestas de otras preguntas en sigprocmask(), los he visto y no aclaran mi pregunta.

enter code here 
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 

int main() 
{ 
sigset_t old_set,new_set; 
sigemptyset(&old_set); 
sigemptyset(&new_set); 

if(sigaddset(&old_set,SIGSEGV)==0) 
{ 
    printf("sigaddset successfully added for SIGSEGV\n"); 
} 
sigprocmask(SIG_BLOCK,&old_set,NULL); // SIGSEGV signal is masked 
kill(0,SIGSEGV); 


//***************************************************************** 

if(sigaddset(&new_set,SIGRTMIN)==0) 
{ 
    printf("sigaddset successfully added for SIGRTMIN\n"); 
} 
    sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGRTMIN signal is masked 
kill(0,SIGSEGV); 

//****************** Unblock one signal at a time ****************** 

sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGRTMIN signal is unmasked 
sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGSEGV signal is unmasked 

}

Output: 
[[email protected] signals]# ./a.out 
    sigaddset successfully added for SIGSEGV 
    sigaddset successfully added for SIGRTMIN 
    (Note:SIGSEGV is not received even after sigprocmask(SIG_UNBLOCK,&new_set,&old_set); a second time) 

Respuesta

11

Su premisa es errónea. Todo el conjunto se bloquea y desbloquea con una sola llamada de sigprocmask.

Además, normalmente crearía un conjunto que contiene cada señal que desea bloquear, luego intentaría bloquearlos todos con sigprocmask(SIG_BLOCK, pointer_to_sigset);.

Sin embargo, su código realmente no desbloquea SIGSEGV. Esto es lo que escribiría SIN el manejo de errores, porque haría el fragmento innecesariamente largo. Compruebe todas las funciones de errores, sin embargo, las listas de posibles errores son proporcionados por las páginas man:

/* ... */ 
sigset_t signal_set; /* We don't need oldset in this program. You can add it, 
         but it's best to use different sigsets for the second 
         and third argument of sigprocmask. */ 
sigemptyset(&signal_set); 

sigaddset(&signal_set, SIGSEGV); 
sigaddset(&signal_set, SIGRTMIN); 

/* now signal_set == {SIGSEGV, SIGRTMIN} */ 

sigprocmask(SIG_BLOCK, &signal_set, NULL): /* As i said, we don't bother with the 
               oldset argument. */ 

kill(0,SIGSEGV); 
kill(0,SIGSEGV); /* SIGSEGV is not a realtime signal, so we can send it twice, but 
        it will be recieved just once */ 

sigprocmask(SIG_UNBLOCK, &signal_set, NULL); /* Again, don't bother with oldset */ 

/* SIGSEGV will be received here */ 

Por supuesto, es posible que desee dividir el bloqueo de las señales en dos operaciones sobre conjuntos separados. El mecanismo funciona así: hay un conjunto de señales bloqueadas, que reemplazarían a oldset si proporciona un argumento oldset. Puede agregar a ese conjunto con SIG_BLOCK, eliminar de ese conjunto con SIG_UNBLOCK y cambiar todo el conjunto a su gusto con SIG_SETMASK argumentos de la función sigprocmask.

+0

@kubi: ¿Por qué no estoy recibiendo SIGSEGV? – kingsmasher1

+0

@kubi: No, no creo que todo el conjunto se desbloquea de una vez. Verifique el enlace: http://stackoverflow.com/questions/25261/help-with-sigprocmask. Además, sigprocmask() no bloquea ni desbloquea, es el argumento o el primer parámetro lo que hace que bloquee, desbloquee o enmascare. Entonces, por favor piensa antes de señalarme mal. – kingsmasher1

+0

@ kingsmasher1: ¿Cómo maneja 'SIGSEGV'? ¿Podría pegar un fragmento del código del controlador de señal? ¿La señal se envía correctamente? Verifique los códigos de error de 'sigprocmask' y' kill'. – kubi

0

Como kubi señaló: Aquí está el código modificado, el problema es que, me equivoqué con old_set y new_set. El SIGSEGV se agregó en old_set, que no se desbloqueó, y por lo tanto no recibí la falla de Segmentación (señal SIGSEGV). Gracias a kubi.

enter code here 
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 

int main() 
{ 
sigset_t old_set,new_set; 
sigemptyset(&old_set); 
sigemptyset(&new_set); 

if(sigaddset(&old_set,SIGSEGV)==0) 
{ 
    printf("sigaddset successfully added for SIGSEGV\n"); 
} 
sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGSEGV signal is masked 
kill(0,SIGSEGV); 


//***************************************************************** 

if(sigaddset(&new_set,SIGRTMIN)==0) 
{ 
    printf("sigaddset successfully added for SIGRTMIN\n"); 
} 
if(sigprocmask(SIG_BLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is masked 
{ 
    perror("sigprocmask"); 
} 
kill(0,SIGSEGV); 


//****************** Unblock all signals ****************** 

if(sigprocmask(SIG_UNBLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is unmasked 
{ 
    perror("sigprocmask"); 
} 
}