Questa domanda viene posta a mente di Linux. Viene utilizzato il compilatore GCC.Cosa succede se prendo SIGSEGV e il gestore del segnale causa un altro SIGSEGV?
Quale comportamento ci si può aspettare se SIGSEGV (intendo una violazione che normalmente causa SIGSEGV) si verifica all'interno di un gestore di segnali il cui scopo era catturare SIGSEGV? Esempio di codice per aiutare la discussione:
/* In main or whatever */
{
struct sigaction sa = {}; /* initialised to all zero (I vote for GCC style breach of standard here) */
sa.sa_handler = DisasterSignals;
sa.sa_flags = SA_RESETHAND | SA_NODEFER; /* To have or have not */
sigaction(SIGSEGV, &sa, NULL);
}
static void DisasterSignals(int signal)
{
/* We cannot save the situation, the purpose of catching the signal is
only to do something clever to aid debugging before we go. */
/* Q: What if we segfault in here?? */
abort(); /* This should give us the expected core dump (if we survive to this point) */
}
Immaginate, nel punto "Q", C'è un'istruzione macchina incriminato.
1) Senza il SA_RESETHAND | SA_NODEFER
: Sembra che il sistema si trovi in una trappola logica: in "Q", SIGSEGV deve essere generato. Ma SIGSEGV è bloccato nel gestore di segnale (comportamento di sigaction predefinito). Come può continuare l'esecuzione? Si congela? Supererà l'istruzione incriminata (credo di no)?
2) Con il SA_RESETHAND | SA_NODEFER
: Credo che in questo caso il programma si arresti in modo "normale" quando SIGSEGV viene ripetuto.
3) con solo SA_NODEFER
: suppongo che in questo caso il gestore di segnale venga chiamato in modo ricorsivo quando SIGSEGV viene ripetuto; se SIGSEGV viene sempre ripetuto, otteniamo un congelamento fino a quando lo stack non trabocca, e poi cosa.
Quis custodiet ipsos custodes? –
Si suppone che si chiamino solo le funzioni di rientro nei gestori di segnale. – edmz
Cosa succede quando un proiettile perforante piercing un'armatura? – mah