IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

interruption : segmentation fault


Sujet :

C

  1. #1
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut interruption : segmentation fault
    Bonjour à tous ,
    je voudrais savoir comment et pourquoi un appel de procédure
    est capable de générer l'interruption : segmentation fault

    nb: je compile du C avec gcc sous linux.

  2. #2
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Quelques explication ici:
    [ame]http://fr.wikipedia.org/wiki/Erreur_de_segmentation[/ame]

  3. #3
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    Merci pour l'article mais tout cela je le sait déjà ...
    Je répète donc la question : comment est-il possible d'obtenir un
    segmentation fault provoqué par un appel de procédure ,car c'est
    bien cet appel (et pas autre chose) qui provoque la faute !!

  4. #4
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Sans nous montrer la partie de ton code qui plante on ne peux pas être plus précis.

    As-tu vérifié que les paramètres que tu donne en entrée de ta procédure sont corrects?

    Que les variables passées en paramètres sont allouées et ne pointent pas sur des données invalides?

    Que ta procédure ne nécessite pas certains pré-requis qui ne sont pas remplis?
    ....

    Même avec des fonctions standard on peux provoquer un segfault si les paramètres d'appel sont incorrect.


    Exemple simple qui donne un segfault:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
     
     int main()
    {
         int variable_entiere;
         scanf("%d", &variable_entiere); //correct
         printf("valeur=%d\n",variable_entiere);
    
         scanf("%d", variable_entiere); // segfault
         printf("valeur=%d\n",variable_entiere);
    }

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 444
    Par défaut
    Citation Envoyé par exe2bin Voir le message
    Merci pour l'article mais tout cela je le sait déjà ...
    Je répète donc la question : comment est-il possible d'obtenir un
    segmentation fault provoqué par un appel de procédure ,car c'est
    bien cet appel (et pas autre chose) qui provoque la faute !!
    Un appel de procédure en C ? Hmm.

    Comme le dit Jabbounet, il est peu probable que ce soit l'appel d'une fonction en lui-même qui fasse planter l'affaire, mais plutôt des paramètres initialement invalides exploités par la fonction. Sinon, le seul moyen de faire un appel engendrant une segfault est d'utiliser un pointeur de fonction invalide. Est-ce le cas ?

    Sinon, montre-nous ton code.

  6. #6
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    Bien evidement que cela est bizare sinon je ne poserais pas la question ;
    en ce qui concerne le code je ne peux tout mettre mais on va essayer de
    procéder par étapes .
    la procédure appelante est main et la fonction appelée est la procédure
    struct machin *Defiler(void) d'une file implémentée à l'aide d'une liste chainée en laquelle j'ai toute confiance pour 2 raisons : 1)elle fonctionne en dehors de ce programme et
    (ce qui est pire) 2)main appelle sans aucun problèmes cette procédure plusieurs fois sans soucis !!
    Donc ,il se trouve que lors d'un ultime appel ,le plantage s'effectue sans que
    l'execution soit passée à la fonction ?!
    J'en suis sûr puisque la première instruction de cette fonction est un printf().
    Voilà l'affaire

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 444
    Par défaut
    Citation Envoyé par exe2bin Voir le message
    Bien evidement que cela est bizare sinon je ne poserais pas la question ;
    J'insinue par là que l'on n'utilise pas cette terminologie en langage C.

    la procédure appelante est main et la fonction appelée est la procédure
    struct machin *Defiler(void)
    Merci d'utiliser les balises [ CODE ] (le bouton « # » dans la fenêtre d'édition) pour poster un extrait de code. Pose quand même ton code ici. Au moins le contenu de main(), et le début de Defiler().

    … d'une file implémentée à l'aide d'une liste chainée en laquelle j'ai toute confiance pour 2 raisons : 1) elle fonctionne en dehors de ce programme et
    (ce qui est pire) 2)main appelle sans aucun problèmes cette procédure plusieurs fois sans soucis !!
    Et bien, quand tu as passé en revue toutes les causes probables de plantage, il faut commencer à te pencher sur ce que tu avais écarté d'emblée.

    Donc ,il se trouve que lors d'un ultime appel ,le plantage s'effectue sans que l'execution soit passée à la fonction ?! J'en suis sûr puisque la première instruction de cette fonction est un printf(). Voilà l'affaire
    Et − justement − si tu avais lu les commentaires précédents, tu aurais compris que ce n'est pas un alibi suffisant. Le programme ci-dessous commence également par un printf(). À ton avis, que va-t-il se passer si tu l'exécutes ? Compile cet exemple et lance-le si tu ne le sais pas :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
     
    int main (void)
    {
        printf ("%s\n",(const char *)1);
     
        return 0;
    }

  8. #8
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    C'est évident ,quand on cherche les ennuis on les trouve ...
    Un code comme ça on en rencontre pas tous les jours.
    Bon ,je vais essayer de donner des bouts de code mais ça va pas etre
    facile car la machine que j'utilise tourne sur linux sans port usb alors il va falloir que j'achete des diskettes et puis monter la partition puis formater pour fat32 pour enfin joindre les fichiers ,hum !
    Je peux decement pas taper + de 100 lignes de codes !!!
    Mon printf() à moi il est tout bête ,c'est un print de debboguage histoire de savoir si l 'execution passait par là ;du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("coucou je suis dans la fonction Defiler()");
    Tant pis je passe

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 444
    Par défaut
    Citation Envoyé par exe2bin Voir le message
    C'est évident ,quand on cherche les ennuis on les trouve ... Un code comme ça on en rencontre pas tous les jours.
    Et c'est vrai dans l'autre sens aussi : si tu refuses de voir les erreurs là où elles peuvent être, tu ne risques pas de les trouver.

    Cet exemple de code est là pour te montrer qu'il est tout-à-fait possible d'écrire un code légal avec une fonction système qui compile parfaitement et qui, pourtant, plante avant d'avoir affiché le premier caractère…

    Il y a neuf chances sur dix que la fonction que tu appelles plante parce que tu lui as passé un paramètre pourri quelque part. Ça peut être directement dans les arguments de la fonction, mais ça peut aussi être dans les membres de ta structure. Et le fait que ça ne plante pas ailleurs n'est pas une raison valable : il y a des dizaines de choses qui peuvent rendre ton bug intermittent.

    Bon ,je vais essayer de donner des bouts de code mais ça va pas etre
    facile car la machine que j'utilise tourne sur linux sans port usb alors il va falloir que j'achete des diskettes et puis monter la partition puis formater pour fat32 pour enfin joindre les fichiers ,hum ! Je peux decement pas taper + de 100 lignes de codes !!!
    Il n'y a pas de réseau non plus sur ta machine ? Si vraiment il n'y en a pas, il te coûtera sans doute moins cher, en temps et en argent, d'acheter une carte Ethernet bon marché et un câble.

    Mon printf() à moi il est tout bête ,c'est un print de debboguage histoire de savoir si l 'execution passait par là ;du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("coucou je suis dans la fonction Defiler()");
    Rien que dans ce que tu as écrit, il y a déjà une erreur : il manque le retour à la ligne. Si c'est vraiment de cette façon que tu l'as rédigée dans ton code, alors ton message va rester un moment dans le tampon avant d'être affiché et il se peut que l'erreur se produise beaucoup plus loin que tu le crois.

    Sinon, si tu veux savoir tout de suite où se produit l'erreur, il y a un outil formidable pour ça : gdb.

  10. #10
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    Tu veux dire connecter les 2 ordis ensemble ? Je sais pas faire ça ; par contre si tu pouvais m'en dire un peu plus sur gdb (comment on s'en sert) ça serait un bon début.
    Merci

  11. #11
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    +1 gdb un outil indispensable.

    En résumé (vite fait, mal fait):
    pour savoir exactement ou cela plante, il faut compiler ton application avec les options de debug "-g" pour gcc/g++

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    gcc -g monprog.c -o monprog
    Ensuite deux méthodes ensuite sont possible

    1/ debug normal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    gdb monprog
    run
    bt
    bt est à lancer une fois planté


    2/ methode post mortem

    Autoriser la génération de fichier core dump.
    dans le shell ou lance le programme.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ulimit -c unlimited
    Lancer ton programme pour qu'il génère un fichier core
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    monprogr ...
    segfault(core dumped)
    faire un debug post mortem avec le fichier core generé pour savoir exactement ou ça plante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    gdb monprog core
    bt

    les deux méthodes sont a peu près équivalente un fois l'application planté.

    Cependant la première à l'avantage qu'elle te permet de placer des points d'arrêt, de faire des exécutions pas à pas de ton programme, ..... mais pour cela il faut regarder un peu les tutoriel pour voir comment ça marche.

  12. #12
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    et en ce qui concerne le suivi de traces, fprintf ( stderr, est bien plus pratique que printf, car il a l'énorme avantage d'être synchrone.. C'est à dire que ce qui n''est pas écrit n'a pas été exécuté, contrairement à printf..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Pb segmentation fault avec glutinit()
    Par pipistrelle dans le forum GLUT
    Réponses: 2
    Dernier message: 17/11/2004, 23h17
  2. [SDL_Image] Img_Load : segmentation fault ....
    Par Mathieu.J dans le forum OpenGL
    Réponses: 6
    Dernier message: 19/10/2004, 23h52
  3. [REDHAT] Segmentation fault systematique
    Par mela dans le forum RedHat / CentOS / Fedora
    Réponses: 2
    Dernier message: 21/09/2004, 06h05
  4. Réponses: 13
    Dernier message: 13/07/2004, 15h41
  5. Comment contrer la "segmentation fault" ?
    Par guillaume_pfr dans le forum C
    Réponses: 15
    Dernier message: 08/08/2003, 13h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo