2010-11-13 44 views
0

J'utilise ncurses et chaque fois que je reçois un segfault, ncurses ne libère pas correctement le contrôle du terminal (car endwin() n'a jamais été appelé). Je mis en place un gestionnaire de signal:Enfin un bloc pour les erreurs de segmentation (C++)

void handler(int signum) { 
    endwin(); 
    exit(EXIT_FAILURE); 
} 

mais le problème est que le segfault est ignoré, par opposition à un retard jusqu'à ce endwin(). Je suis assez nouveau pour C++; les segfaults peuvent-ils être pris comme des exceptions, pour que je puisse avoir un bloc finally? Ou est-il possible de renvoyer la segfault depuis l'intérieur du gestionnaire?

+0

duplication possible de [Comment attraper la faute de segmentation sous Linux?] (Http://stackoverflow.com/questions/2350489/how-to-catch-segmentation-fault-in-linux) – casablanca

+0

Juste par intérêt, que arrive si vous mettez un point d'arrêt dans le gestionnaire de signal? Gdb peut-il revenir au contexte de la segfault originale alors? –

+0

C++ n'a pas de blocs finally. Utilisez une classe de sentinelle, dont le destructeur appelle endwin(); –

Répondre

4

Segfault est un comportement indéfini. Vous devez le trouver et le réparer. Ne vous inquiétez pas si ncurses ne libère pas le terminal, et trouvez et corrigez le bogue.

+0

Je suppose que j'aurais dû être plus clair. C'est une question pratique uniquement pour déboguer mon code. Quand je rencontre un segfault, je veux aller le trouver et le réparer, mais c'est vraiment difficile de faire fonctionner GDB quand ncurses n'a toujours pas libéré le terminal. J'ai finalement trouvé ce bogue, mais cela m'a pris plus de temps que prévu, et j'aurai probablement plus de bugs pendant que je continue à coder. Donc, il n'y a aucun moyen de faire ce que je demande? – Nick

+0

@Nick: Lorsque vous frappez un défaut de segmentation, cela signifie que vous avez tellement mal bourré que rien ne sert à continuer car tout ce que vous faites ne fait qu'empirer les choses. –

+0

@Martin York: Ce n'est pas qu'il ne veut pas corriger le bug, c'est que trouver le bug est plus difficile quand toutes les ressources n'ont pas été abandonnées. Imaginez si vous deviez redémarrer votre ordinateur à chaque fois pour corriger un déréférencement de pointeur nul, ne voudriez-vous pas trouver un moyen d'éviter le redémarrage? – dreamlax

0

De la page man signal:

Selon POSIX, le comportement d'un processus est indéfini après qu'il ignore un SIGFPE, SIGILL, ou SIGSEGV qui n'a pas été généré par kill (2) ou augmenter (3).

Essayer de faire quoi que ce soit après un défaut de seg est fou. C'est comme l'airbag dans votre activation après un accident et vous continuez à conduire, parce que, eh bien, vous avez un airbag et il vous gardera en sécurité dans un accident. Papering dessus avec un gestionnaire n'est pas le chemin. L'une des façons serait de faire en sorte que votre programme prenne des entrées à partir d'un fichier ou en supprime la sortie. Vous pouvez également essayer remotely attaching to a process with gdb. Je n'ai jamais fait ça mais ça vaut le coup d'essayer.

+0

Non, c'est comme si vous écrasiez votre voiture et pensiez: "Hey, je devrais probablement prendre mon enfant avant de sortir du véhicule en feu." (L'enfant dans ce cas est le terminal.) Le débogage distant peut fonctionner, mais il semble impliqué. Je pourrais essayer peut-être, mais je préfère l'avoir comme un dernier recours extrême. – Nick