2010-05-20 6 views
81

Comment pouvons-nous déterminer où l'erreur est dans notre code qui provoque un segmentation fault?Déterminer la ligne de code qui provoque une erreur de segmentation?

Après avoir écrit du code, pour déterminer où j'ai une erreur de segmentation, mon compilateur (gcc) peut-il me montrer l'emplacement de l'erreur dans mon programme?

+2

Aucun gcc/gdb ne peut pas. Vous pouvez trouver _where_ le segfault survenu, mais l'erreur réelle pourrait être à un endroit totalement différent. –

Répondre

121

GCC ne peut pas faire cela mais GDB le peut. Compilez vous programme à l'aide du commutateur -g, comme ceci:

gcc program.c -g 

Ensuite, utilisez gdb:

$ gdb ./a.out 
(gdb) run 
<segfault happens here> 
(gdb) backtrace 
<offending code is shown here> 

Here est un tutoriel agréable pour vous aider à démarrer avec GDB.

+9

L'utilisation du backtrace de gdb ('bt') permettra de trouver rapidement où cela s'est passé. – nategoose

+1

@nategoose: Vrai :) – nc3b

+12

Notez que là où le segfault se produit est généralement seulement un indice quant à où "l'erreur qui cause" il est dans le code.Un indice important, mais ce n'est pas nécessairement là où réside le problème. – mpez0

13

Vous pouvez également utiliser un vidage de mémoire, puis l'examiner avec gdb. Pour obtenir des informations utiles, vous devez également compiler avec le drapeau -g.

Chaque fois que vous obtenez le message:

Segmentation fault (core dumped) 

un fichier de base est écrit dans votre répertoire courant. Et vous pouvez l'examiner avec la commande

gdb your_program core_file 

Le fichier contient l'état de la mémoire lorsque le programme s'est bloqué. Un core dump peut être utile lors du déploiement de votre logiciel.

Assurez-vous que votre système ne définit pas la taille du fichier de vidage de base à zéro. Vous pouvez le régler à un nombre illimité avec:

ulimit -c unlimited

Attention cependant! que les vidages de base peuvent devenir énormes.

+0

Je suis passé à arch-linux récemment. Mon répertoire actuel ne contient pas le fichier de vidage de base. Comment puis-je le générer? – Abhinav

+0

Vous ne le générez pas; Linux le fait. Les vidages de base sont stockés à différents endroits sur differnt Linuces - Google autour. Pour Arch Linux, lisez ce https://wiki.archlinux.org/index.php/Core_dump – Mawg

2

La réponse de Lucas au sujet des vidages de mémoire est bonne. Dans mon .cshrc j'ai:

alias core 'ls -lt core; echo where | gdb -core=core -silent; echo "\n"' 

pour afficher le backtrace en entrant 'core'. Et le timbre de date, pour assurer que je regarde le bon fichier :(

Ajouté:.. S'il y a un bug de corruption de la pile, le backtrace appliqué à la décharge de base est souvent ordures Dans ce cas, , en exécutant le programme dans gdb peut donner de meilleurs résultats, selon la réponse acceptée (en supposant que la faute est facilement reproductible) Et méfiez-vous aussi de plusieurs processus dumping noyau simultanément, certains systèmes d'exploitation ajoutent le PID au nom du fichier core.

+4

et n'oubliez pas 'ulimit -c unlimited' pour activer les dumps core en premier lieu. –

+0

@James: Correct. Lucas a déjà mentionné cela. Et pour ceux d'entre nous qui sont encore coincés dans le csh, utilisez 'limit'. Et je n'ai jamais pu lire les stack stack de CYGWIN (mais je n'ai pas essayé depuis 2 ou 3 ans). –

24

Aussi, vous pouvez essayer Valgrind: si vous installez Valgrind et exécutez valgrind --leak-check = full, alors il lancera votre programme et affichera la pile t courses pour les erreurs de segmentation, ainsi que toute lecture ou écriture de mémoire invalide et les fuites de mémoire. C'est vraiment très utile.

+2

+1, Valgrind est tellement plus rapide/facile à utiliser pour détecter les erreurs de mémoire. Sur les builds non optimisées avec des symboles de débogage, il vous indique _exactly_ où un segfault s'est produit et pourquoi. –

+0

Malheureusement, mon segfault disparaît lors de la compilation avec -g -O0 et combiné avec valgrind. – JohnMudd

Questions connexes