2015-04-20 13 views
5

Sto tentando di ignorare SIGTRAP. Ho la seguente proof-of-concept code:Perché ignorare SIGTRAP non funziona con ASM?

#include <signal.h> 
#include <stdlib.h> 
int main(){ 
    signal(SIGTRAP, SIG_IGN); 
    write(1, "A", 1); 
    asm("int3"); 
    write(1, "B", 1); 
    return 0; 
} 

quando l'eseguo, mi aspetto di vedere "AB", ma vedo

ATrace/breakpoint trap (core dumped) 

Perché il mio programma di terminare nonostante ignorando SIGTRAP ?

+0

Per inciso, quando uso un gestore personalizzato (come questo: 'vuoto SIGTRAP (int signum) {} ') allora vedo correttamente" AB ", ma voglio usare SIG_IGN perché è ereditato dalle chiamate execve. – Chris

+0

Un lato interessante: questo codice viene eseguito "correttamente" (output 'AB') su Mac OS X. – duskwuff

risposta

1

Secondo this site un segnale bloccato/ignorato viene automaticamente sbloccato all'interno del codice del kernel quando viene generato. Quindi, se lo stesso segnale viene sollevato ripetutamente, non si verificherà un ciclo infinito. Invece l'applicazione è terminata sul secondo aumento di segnale, almeno nell'implementazione del kernel Linux.

Quindi, quando si utilizza raise(), il numero SIGTRAP verrà sollevato una sola volta, senza causare problemi. Ma con asm("int3") il processore eseguirà di nuovo l'istruzione che ha generato il segnale. La seconda volta ciò causa la chiusura del processo.

La sorgente del kernel rilevanti (per il vecchio 2.6.27) è qui (funzione force_sig_info):

939  if (blocked || ignored) { 
940    action->sa.sa_handler = SIG_DFL; 
941    if (blocked) { 
942      sigdelset(&t->blocked, sig); 
943      recalc_sigpending_and_wake(t); 
944    } 
945  } 
Problemi correlati