2011-04-26 2 views

Répondre

15

Voici un exemple de programme minimal qui utilise sigaltstack pour intercepter la récursion infinie. Si vous mettez en commentaire l'appel sigaltstack ou le flag SA_ONSTACK, le gestionnaire de signal ne pourra pas s'exécuter car il ne reste plus de pile et le programme ne fonctionnera plus.

#define _XOPEN_SOURCE 700 
#include <signal.h> 
#include <unistd.h> 
void handler(int sig) 
{ 
    write(2, "stack overflow\n", 15); 
    _exit(1); 
} 
unsigned infinite_recursion(unsigned x) { 
    return infinite_recursion(x)+1; 
} 
int main() 
{ 
    static char stack[SIGSTKSZ]; 
    stack_t ss = { 
     .ss_size = SIGSTKSZ, 
     .ss_sp = stack, 
    }; 
    struct sigaction sa = { 
     .sa_handler = handler, 
     .sa_flags = SA_ONSTACK 
    }; 
    sigaltstack(&ss, 0); 
    sigfillset(&sa.sa_mask); 
    sigaction(SIGSEGV, &sa, 0); 
    infinite_recursion(0); 
} 

Une utilisation plus sophistiquée pourrait en fait effectuer siglongjmp sauter du gestionnaire de signal et à un point où l'on peut éviter la récursion infinie. Cela n'est pas valide si les appels de bibliothèque async-signal-unsafe sont utilisés, ou si vos données peuvent être laissées dans un état non sécurisé/irrécupérable, mais si vous effectuez des calculs arithmétiques purs, cela peut être valide. Une meilleure tâche pour le gestionnaire de signal serait peut-être d'effectuer un vidage d'urgence de toutes les données valables/critiques qui n'étaient pas déjà enregistrées sur le disque. Cela peut être difficile si vous ne pouvez pas appeler des fonctions asynchrones, ce qui est généralement possible si vous y mettez un peu d'effort.

+0

ce code ne fonctionne pas .... il m'a donné un défaut de sementation –

+2

Cela fonctionne bien pour moi (après avoir corrigé la faute de frappe). Incidemment, avec l'optimisation activée, gcc génère une boucle infinie plutôt que la récursivité pour la fonction et ne déborde donc jamais la pile. Avec '-O0', le gestionnaire de signal fonctionne comme prévu. –

+0

J'ai essayé avec -O0 comme tu l'as dit mais ça me donne encore un défaut de sementation. Peut-il s'agir de la version gcc? –

Questions connexes