2012-04-20 3 views
0

J'utilise un gestionnaire de signal pour le signal ctrl-c. C'est à chaque fois que le signal ctrl-c est généré au lieu de quitter l'application que je fais une action. Supposons que mon application se bloque en raison de while (1) loop (toute condition d'erreur) est-il possible pour moi de quitter l'application uniquement dans ce cas?en utilisant le gestionnaire de signal pour ctrl-c - besoin d'aide sur les boucles infinies

ex:

void handle() 
{ 
    /*do some action*/ 
    ---- 
    ---- 
    --- 

    if (while(1) detected) 
    { 
    exit(0); 
    } 
} 


main() 
{ 
    struct sigaction myhandle; 
    myhandle.sa_handler = handle; 
    sigemptyset(&myhandle.sa_mask); 
    myhandle.sa_flags = 0; 
    sigaction(SIGINT, &myhandle, NULL); 

    while(1); 
} 

Merci

+0

1) La déclaration/définition/signature pour votre gestionnaire de signal est erronée, elle devrait être 'handle vide (int signum);' 2: recherche 'man 2 siglongjmp' – wildplasser

Répondre

0

Il est très difficile de trouver si votre code est dans une boucle infinie accidentelle avant de recevoir un signal comme Ctrl-C. Je peux suggérer quelques approches heuristiques. Avoir une variable de taille suffisamment longue, de préférence un unsigned long long int global, et continuer à incrémenter cette variable à l'intérieur des boucles que vous suspectez de glisser dans des boucles infinies à chaque itération de la boucle. Maintenant, lorsque vous recevez un signal, vérifiez la valeur de cette variable dans le gestionnaire de signal par rapport à un seuil MAX_NUMBER_OF_ITERATIONS. Si la variable dépasse le seuil défini par l'utilisateur, déclarez alors une boucle infinie et exit sinon continuez simplement.

Quelque chose sur ces lignes-

#define MAX_NUMBER_OF_ITERATIONS 100000000 

unsigned long long checkForEndlessLoop=0; 
bool overflow; 

void sigHandler (int signum) 
{ 
    signal(sig, SIG_IGN); // Ignore it so that another Ctrl-C doesn't appear any soon 
    if (overflow || (checkForEndlessLoop > MAX_NUMBER_OF_ITERATIONS)) 
    { 
     //Something's fishy in the loop. 
     exit(0); 
    } 
    else 
    { 
     signal(SIGINT, sigHandler); 
    } 
} 

int main() 
{ 
    signal(SIGINT, sigHandler); 

    for (checkForEndlessLoop=0; SOME_SLOPPY_CONDITION;) 
    { 
     //Some processing here 
     if (++checkForEndlessLoop == 0) 
      overflow=true; 
    } 

    checkForEndlessLoop=0; 

    while (SOME_SLOPPY_CONDITION) 
    { 
     //Some processing here 
     if (++checkForEndlessLoop == 0) 
      overflow=true; 
    } 

} 

Ou encore plus simple est, simplement ignorer l'SIGINT en utilisant SIG_IGN et break hors de la boucle défectueuse dès que la condition défectueuse est détectée, imprimer un message d'erreur et Sortie!

+0

2) siglongjmp 3) déclarez votre variable de condition comme" volatile "pour éviter que le compilateur cache sa valeur. – wildplasser

Questions connexes