Flux rss

[Langage C] C/C++ Erreur de segmentation

Publié par kilian, dernière mise à jour le samedi 8 septembre 2007 à 14:21:52 par kilian

Qu'est ce qu'une erreur de segmentation



Vous êtes en train de développer une application sous Linux en
C/C++. Tout va bien, ça compile, les oiseaux chantent.
Donc vous lancez votre application pour la tester.

Et vous obtenez l'un de ces deux messages:
Erreur de segmentation

ou
Segmentation fault

Autant lorsque vous avez une erreur avec un programme écrit dans un langage de très haut niveau (perl, python, java etc...), vous aurez un message de debuggage détaillé: quel type d'exception s'est produit? A quel ligne du programme ça correspond etc...
Autant avec un langage compilé (donc transformé en langage directement compréhensible par votre processeur) comme c ou c++, votre programme n'est sous la tutelle d'aucun interpréteur ou machine virtuelle. Donc personne pour surveiller vos erreurs et les analyser.

Heureusement il existe des programmes appelés debuggeurs et qui sont là pour vous faciliter la tâche.

Il faut savoir qu'un système d'exploitation moderne (Windows nt/2000/XP/ ; Linux) alloue une portion de mémoire pour chaque application. Si une application essaie de pénétrer directement dans une zone-mémoire qui ne lui appartient pas ou dans une zone mémoire incorrecte, le système d'exploitation va stopper l'application en cours et va générer une erreur (sous Linux: Erreur de segmentation)

En C


Prenons par exemple un programme en C tout à fait débile qui se plante volontairement et génère une erreur de segmentation:

void lance_erreur_segmentation()
{
	int *pointeur_dangereux=(int *) 100;
	int test=*pointeur_dangereux;
}

int main(int argc, char ** argv)
{
	lance_erreur_segmentation();
	return 0;
}


Dans la fonction lance_erreur_segmentation, le pointeur_dangereux pointe vers l'adresse 100 dans la mémoire.
C'est une adresse qui ne peut pas appartenir à une application normale.
Au moment où pointeur_dangereux tentera de lire ce qu'il ya dans l'adresse mémoire 100 pour mettre la valeur située à cette adresse dans la variable test, le programme va crasher.
Et vous obtiendrez le message "Erreur de segmentation".

Pour débugger ce programme nous allons commencer par le compiler en lui chargeant ses symboles de débuggage. Cela permet notamment de charger les noms de fonctions et variables utilisés dans le programme une fois qu'il est compilé, ainsi le debugger pourra tracer l'erreur en vous indiquant les noms des fonctions concernées plutôt que de donner juste leur adresse.
Je parle ici de l'option -g

On compile:
gcc -g test.c -o test

Et on lance le programme dans le debugger:
gdb ./test

Vous allez apercevoir une invite de commande commençant par:
(gdb)

Tapez la commande run

Observons ce qu'il se passe:
(gdb) run
Starting program: /home/chantecode/Desktop/test 

Program received signal SIGSEGV, Segmentation fault.
0x08048334 in lance_erreur_segmentation () at test.c:4
4               int test=*pointeur_dangereux;


Que demander de plus: le debuggeur vous indique la ligne dans votre fichier source qui est à l'origine de l'erreur, ainsi que la fonction concernée et le contenu de la ligne:
C'est une erreur dans la fonction lance_erreur_segmentation dans le fichier source test.c à la ligne 4 dont le contenu est
int test=*pointeur_dangereux;


Admettons maintenant que vous vouliez savoir quelle fonction a appelé quelle autre fonction depuis le début du programme jusqu'à l'arrivée de l'erreur.

Tapez la commande bt:
(gdb) bt
#0  0x08048334 in lance_erreur_segmentation () at test.c:4
#1  0x0804834e in main () at test.c:9

Et vous avez encore une fois ce qu'il vous faut :-)

En C++


Pour en rester au même problème: les erreurs de segmentation, il n'y a pas grand chose à ajouter pour le C++, hormis qu'il s'agit d'utiliser la commande g++ avec l'option -g de la même façon qu'avec gcc.

Le rapport de gdb sera le même mais avec des détails sur les classes concernées.

Exemple:
//Fichier test.cpp
class Test{
	public:
		int a;
		Test(){};
		~Test(){};
		int incremente_a(){ a++; };
};

int main()
{
	Test *t;
	t=(Test *)100;
	t->incremente_a();
	return 0;
}

On compile comme ceci:
g++ -g test.cpp -o test


On lance le déboggeur:
gdb ./test

Puis on y tape les mêmes commandes qu'avant et tous les détails s'affichent:
(gdb) run
Starting program: /home/chantecode/Desktop/test 

Program received signal SIGSEGV, Segmentation fault.
0x080483fc in Test::incremente_a (this=0x64) at test.cpp:7
7                       int incremente_a(){ a++; };
(gdb) bt
#0  0x080483fc in Test::incremente_a (this=0x64) at test.cpp:7
#1  0x080483e7 in main () at test.cpp:14


Et voilà.

Liens


_ Excellent tutoriel sur le déboggage C++ en utilisant gdb de manière plus agréable(fr)

Résultats pour C/C++ Erreur de segmentation

Code erreur 81000306 (Résolu) j'ai le code erreur 81000306 je n'arrive pas à me connecter .comment faire?MERCI DE M'AIDER www.commentcamarche.net/forum/affich-3397797-code-erreur-81000306
[Vista] Windows update : code erreur 8024402C (Résolu) Bonjour, Voici, mon problème : sous Vista Enterprise officiel et activé lorsque je lance Windows update, j'obtiens un code erreur 8024420C. J'ai parcouru sans succès toutes les pistes des forums à ce sujet (config IE, exceptions dans les... www.commentcamarche.net/forum/affich-2877737-vista-windows-update-code-erreur-8024402c
Code erreur 80072745 (Résolu) Bonjour tout le monde, je vous explique ma situation : j'étais tranquilou sur windows live messenger hier soir et d'un coup d'un seul, il s'est déconnecté. Essayant de le reconnecter, j'ai le code erreur 80072745 qui... www.commentcamarche.net/forum/affich-5828152-code-erreur-80072745

Résultats pour C/C++ Erreur de segmentation

Ma clé USB est reconnue comme un Digital Audio PlayerProblématique Manipulation à effectuer Source Problématique Certaines clés USB sur Ubuntu ne sont pas détectées comme des clés USB "classiques", mais comme des lecteurs de musique type iPod. Cette erreur provoque le lancement d'un lecteur... www.commentcamarche.net/faq/sujet-10844-ma-cle-usb-est-reconnue-comme-un-digital-audio-player
[Windows Live Messenger] Erreur 8004800ELa version bêta de Windows Live Messenger 8.1 (WLM) renvoie parfois l'erreur 8004800E. Cette erreur, qui sera a priori corrigée dans la version suivante, peut être éliminée de la manière suivante : Quitter complètement Windows Live... www.commentcamarche.net/faq/sujet-4690-windows-live-messenger-erreur-8004800e
[Windows] Accès impossible au panneau de configurationLorsque vous souhaitez accéder au panneau de configuration, un message indique "Explorer.exe a généré une erreur" ou bien l'accès est tout simplement impossible : Accès restreint par administrateur Cette erreur est généralement liée à une... www.commentcamarche.net/faq/sujet-2573-windows-acces-impossible-au-panneau-de-configuration

Résultats pour C/C++ Erreur de segmentation

Code erreur 80073712 (Résolu)Bonjour, depuis quelques temps je n'arrive plus à télécharger des mises à jour pour windows vista.Le système m'affiche le message suivant : "Erreurs détectées: code erreur 80073712 " Je ne sais pas si quelqu'un peut me venir en... www.commentcamarche.net/forum/affich-5327786-code-erreur-80073712
Code erreur 80048831 (Résolu)Bonjour, sur Windows live messenger comment faire pour se débarrasser du code erreur 80048831 pour pouvoir se reconnecter d'avance merci www.commentcamarche.net/forum/affich-4050445-code-erreur-80048831
Code erreur 81000314 pas de connection a msn (Résolu)bonjour a tous depuis 12h impossible de me connecter a msn il me dise code erreur : 81000314 ou code erreur 81000306 ça change tout le temps ! et quand je fais dépanner et il me dit vos fichiers hosts contient des entrées liés à orange messenger by... www.commentcamarche.net/forum/affich-8371896-code-erreur-81000314-pas-de-connection-a-msn