2012-01-19 13 views
5

Ecco il codice su cui ho impostato il mio gestore per il segnale SIGABRT, quindi chiamo il abort() ma il gestore non viene tratteggiato, invece il programma viene interrotto, perché?Come gestire il segnale SIGABRT?

#include <iostream> 
#include <csignal> 
using namespace std; 
void Triger(int x) 
{ 
    cout << "Function triger" << endl; 
} 

int main() 
{ 
    signal(SIGABRT, Triger); 
    abort(); 
    cin.ignore(); 
    return 0; 
} 

PROGRAMMA DI USCITA:

enter image description here

+0

Opere qui, dopo aver incluso ''. Quale piattaforma? –

+0

Windows 7 x64 con MSVC++ 2010 (non è necessario includere cstdlib in visual studio) – codekiddy

+1

Bene, il programma dovrebbe essere interrotto a meno che i gestori di segnale non eseguano un 'longjmp'. Se vuoi che il messaggio venga stampato prima, potresti voler scaricare 'std :: cout' (o scrivere in' std :: cerr'). –

risposta

11

Come altri hanno già detto, non è possibile annullare il comando abort() e consentire che l'esecuzione continui normalmente. Quello che puoi fare è proteggere un pezzo di codice che potrebbe essere annullato da una struttura simile a una presa di prova. L'esecuzione del codice verrà interrotta, ma il resto del programma può continuare. Ecco una demo:

#include <csetjmp> 
#include <csignal> 
#include <cstdlib> 
#include <iostream> 

jmp_buf env; 

void on_sigabrt (int signum) 
{ 
    longjmp (env, 1); 
} 

void try_and_catch_abort (void (*func)(void)) 
{ 
    if (setjmp (env) == 0) { 
    signal(SIGABRT, &on_sigabrt); 
    (*func)(); 
    } 
    else { 
    std::cout << "aborted\n"; 
    } 
}  

void do_stuff_aborted() 
{ 
    std::cout << "step 1\n"; 
    abort(); 
    std::cout << "step 2\n"; 
} 

void do_stuff() 
{ 
    std::cout << "step 1\n"; 
    std::cout << "step 2\n"; 
}  

int main() 
{ 
    try_and_catch_abort (&do_stuff_aborted); 
    try_and_catch_abort (&do_stuff); 
} 
+0

Sembra che questa risposta non sia finita. Nota: ? – stanm

6

Anche se è possibile sostituire gestore per SIGABRT e abort() presterà attenzione al gestore, l'interruzione è soltanto inibito se il gestore di segnale non ritorna. La citazione rilevante in C99 è in 7.20.4.1 paragrafo 2:

L'annullare la funzione causa l'interruzione anomala del programma a verificarsi, a meno che il SIGABRT segnale viene catturato e il gestore di segnale non ritorna. ...

Il gestore di segnale viene restituito e quindi il programma viene interrotto.

+0

Quindi stai dicendo che try_and_catch_abort sopra funzionerà solo in modalità debug e non per codice rilasciato? – Michele

2

È possibile ottenere quei sintomi cioè la finestra di pop-up di debug, quando si dispone di una build di debug (con Windows e Visual Studio-sto testando con la versione 2012), dal momento che imposta una pausa di debug , nell'implementazione di debug di abort()). Se si sceglie "Ignora" si ottiene il messaggio "triger Funzione"

Se fate una build di rilascio, quindi non si ottiene la finestra di debug a comparsa, e si ottiene il messaggio, come previsto perfettamente