Diese Frage wird unter Linux gestellt. GCC-Compiler wird verwendet.Was passiert, wenn ich SIGSEGV abfange und der Signalhandler einen anderen SIGSEGV verursacht?
Welches Verhalten kann erwartet werden, wenn SIGSEGV (ich meine eine Verletzung, die normalerweise SIGSEGV verursacht) innerhalb eines Signalhandlers auftritt, dessen Zweck es war, SIGSEGV zu fangen? Codebeispiel wird die Diskussion zu unterstützen:
/* 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) */
}
Stellen Sie sich vor, in dem Punkt „Q“, gibt es einen säumigen Maschinenbefehl.
1) Ohne die SA_RESETHAND | SA_NODEFER
: Dies scheint das System in eine logische Falle zu setzen: Bei "Q" sollte SIGSEGV generiert werden. Aber SIGSEGV ist im Signalhandler blockiert (Standard-sigaction-Verhalten). Wie kann die Ausführung fortgesetzt werden? Wird es einfrieren? Wird es an der beleidigenden Anweisung vorbeikommen (ich denke nicht)?
2) Mit der SA_RESETHAND | SA_NODEFER
: Ich denke, in diesem Fall wird das Programm auf eine "normale" Art und Weise abstürzen, wenn SIGSEGV wiederholt wird.
3) Mit nur SA_NODEFER
: Ich denke, in diesem Fall wird der Signalhandler rekursiv aufgerufen, wenn SIGSEGV wiederholt wird; Wenn der SIGSEGV immer wiederholt wird, erhalten wir ein Einfrieren, bis der Stapel überläuft, und was dann.
Quis custodiet ipsos custodes? –
Sie sollten nur Wiedereintrittsfunktionen in Signalhandlern aufrufen. – edmz
Was passiert, wenn eine panzerbrechende Kugel die Panzerung durchbohrt? – mah