Ich habe an einigen Buggy-Code gearbeitet und wollte einen SIGSEGV-Handler installieren, um weitere Informationen über den Absturz zu erhalten. Ich habe jedoch festgestellt, dass mein Handler nicht aufgerufen wird.Catching SIGSEGV, wenn durch korrupten Stack ausgelöst
Ich habe nach einem Grund gesucht und es scheint, dass es mit einem korrupten Stack-Pointer-Wert zu tun hat (es wird nicht sicher maskiert). Hier ist ein Proof-of-Concept-Code schrieb ich bis zu überprüfen:
static void catch_function(int sig, siginfo_t *info, void *cntxt)
{
puts("handler works");
}
void main(int argc, char **argv)
{
struct sigaction sa;
sa.sa_sigaction = (void *)catch_function;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO | SA_NODEFER ;
sigaction(SIGSEGV, &sa, NULL);
puts("testing handler");
raise(SIGSEGV);
puts("back");
__asm__ ( "xor %rax, %rax\n\t"
"mov %rax, %rsp\n\t"
"push 0"
);
// never reached...
}
Die Idee RSP ist auf 0 gesetzt (ungültig Offset) und dann für etwas verwenden. Dieser zweite SIGSEGV wird jedoch nicht vom Handler abgefangen, sondern beendet stattdessen den Prozess.
Offenbar benötigt der Aufruf des Signalhandlers einen vernünftigen Stack-Pointer, um damit zu beginnen - aber warum? Ist das nicht gegen die Idee, mit Signalen umzugehen? Irgendeine Chance, das zu umgehen?
Ich verwende Linux Version 3.19.0-25-Generic.
'sigaltstack()'. – EOF
@EOF - Danke; Das sieht vielversprechend aus. Wird die Lösung erfolgreich veröffentlichen. – HairyNopper
können Sie versuchen, Ihr Programm in Valgrind auszuführen? – bruceg