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 :

Segmentation Fault incomprehensible


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Avril 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 35
    Par défaut Segmentation Fault incomprehensible
    Bonjour,

    Mon code plante a l'execution avec le message d'erreur "segmentation fault" et, apres plusieurs heures d'arrachage de cheveux je n'arrive pas a resoudre le probleme.

    Pour expliquer mon probleme :
    - le programme lance une boucle de 150000 itérations ac les memes actions a chaque fois et plante au bout d'environ 110000 itérations
    - biarre : le programme ne plante jamais lors de la meme itération, un cous de sera 109987, l'autre coups ce sera 109567 (toujours assez proche de 109/110k mais jamais au meme endroit)... Je ne pas comment c'est ossible car il n'y a rien d'aléatoire dans mon programme donc je m'attendrai a ce que ca plante toujours au meme moment ou que ca plante pas du tout.
    - le code plante a l'appel d'une function virtuelle par une sous classe, Cette function est appele a chaque iteration sans probleme mais plante alors que ce sont exactement les memes éléments....

    Voila, si vous avez une quelconque idée du type d'erreur qui pourrait expliquer mon probleme, en particulier les cas ou on peut avoir un programme qui plante de maniere "aléatoire" sans raison particulière.

    Y a t-il moyen lorsqu'on l'on a ce type d'erreur d'avoir une explication plus approfondie (que simplement "Segmentation Fault") de ce qui a cause l'erreur ? En utilisant les debuggueur des IDE genre QT Creator ca peut m'aider peut-être ? Pour debugguer un programme quels sont les methodes efficaces / conseillés ? Car je suis débutant et ce que je fais est assez manuel en général : je mets des std::cout un peu partout dans le programme puis je le lance pour voir ou ca plante et je me demandais si il y avait plus simple et efficace....

    Merci pour votre aide !

  2. #2
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Si le programme plante toujours entre la 109k et la 110k itération, on ne peut plus vraiment parler de plantage aléatoire, juste une petite incertitude sur l'itération précise.

    Quant à l'origine du problème, ce n'est souvent pas à la ligne où se produit la "segmentation fault" que se trouve le bug. Il s'agit d'une tentative d'accès en dehors des zones allouées.
    Les causes fréquentes sont les déréférencement de pointeur nul, non initialisé, libéré, hors scope, l'écriture au delà de la fin d'un tableau, des excès de récursivité, des accès simultanés par plusieurs threads, etc.

    Il existe pas mal d'outils permettant de surveiller et déboguer les accès mémoire, l'un des plus connus étant valgrind.

  3. #3
    Invité
    Invité(e)
    Par défaut
    salut,

    lorsque tu seg, tu peux générer un core (voir ulimit), puis utiliser gdb sur ton core pour avoir les dernières instructions avant le crash. Après comme pour toi c'est aléatoire je suis pas sûr que ca t'aide beaucoup.

    Comme ca arrive aux alentours des 100k, je verrais bien une fuite mémoire et une alloc refusée à partir d'une certaine itération..
    du coup (c'est jamais perdu) installes également valgrind (memcheck) et lance valgrind dessus pour voir si tu fuites pas.

  4. #4
    Membre averti
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Avril 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 35
    Par défaut
    Merci pour vos reponses !

    Bon j'ai lance le memcheck de valgrind (sous Qt Creator Analyse--> Valgrind memory check) et la..... le code tourne parfaitement jusque la fin, je comprends pas du tout.

    Lorsque je le lance en ligne de commande dans la console sous linux ca plante mais pas lancer en "memory check".

  5. #5
    Membre chevronné
    Profil pro
    Consultant en technologies
    Inscrit en
    Octobre 2013
    Messages
    158
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en technologies

    Informations forums :
    Inscription : Octobre 2013
    Messages : 158
    Par défaut
    Ca s'appelle un Heisenbug

    * Est-ce que ton code est multithread ? Une data-race peut produire ce genre de bug (tu veux lire une variable initialisé par un autre thread, sauf qu'un jour le thread a pas eu le temps de finir...) puis lorsque tu instrumente le code tout à coup le thread a tout le temps le temps de finir. À nouveau Valgrind peut t'aider http://valgrind.org/docs/manual/hg-manual.html (Si ton projet est petit un papier et un crayon aussi)

    * Est-ce que ton code utilise des pointeurs (nus) ? Un pointeur effacé sous certaines conditions alors que tu dois encore y avoir accès peut provoquer ce genre de problème.

    Je dirais donc Valgrind (ou équivalent), remplacement/habillage des pointeurs. c'est quelques jours de boulots pas marrant, mais si ca résoud pas ton bug ca en résoudra d'autres que t'as pas encore vu.

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Comme les autres te l'ont déjà indiqué, une erreur de segmentation n'est que le symptôme du fait que tu es aller charcuter la mémoire de ton application. C'est le symptôme, pas la cause qui, elle, peut avoir énormément d'origines (la plupart ont d'ailleurs déjà été citées au moins une fois).

    Si ton programme fonctionne correctement en mode débug alors qu'il plante lamentablement en mode release, tu ne dois y voir qu'une chose : la confirmation du symptôme représenté par l'erreur de segmentation : tu vas bel et bien, à un moment donné, charcuter la mémoire et y foutre le bordel.

    Il faut en effet avoir conscience de deux choses :
    • le mode débug contient énormément d'informations supplémentaires par rapport au mode release : données de débuggage, instructions qui n'apparaissent dans le code binaire qu'en mode débug (assertion), et bien d'autres choses. Cela ralenti forcément l'exécution du programme
    • Le mode débug peut faire certaines choses que le mode release ne peut pas forcément, comme initialiser (ou réinitialiser) des pointeurs à des adresses spécifiques (voir à null), ajouter des symboles que le débuggeur poura utiliser, ... Tout cela pour permettre au débuggueur de faire son travail et de nous laisser voir "les entrailles" de l'application

    Et, si tu ajoutes là dessus des outils d'analyses dynamique (comme valgring), tu perds encore -- du fait de l'utilisation de l'outil -- un tout petit peu de performances (il faut bien qu'il tienne le compte de toutes les ressources allouées et libérées ).

    Tout cela pour dire que le fait que le symptôme (l'erreur de segmentation) disparaisse en mode debug ou lorsque tu utilises valgrind est justement la preuve que, sans le code, nous ne pourront absolument rien faire.

    Par contre, ce que nous pouvons faire, c'est te donner quelques pistes à explorer par toi-même :
    1. Evites les pointeurs à chaque fois que leur usage n'est pas indispensable : les références (éventuellement) présentent souvent une alternative bien plus sécurisante
    2. Utilises les pointeurs intelligents (std::unique_ptr, std::shared_ptr)chaque fois que possible
    3. Chaque fois que tu écris un delete sur un pointeur, veille à l remettre à NULL (ou plutôt nullptr)
    4. Chaque Avant chaque tentative d'accès à un pointeur, vérifie sa validité en t'assurant qu'il n'est pas égal à NULL (nullptr).
    5. Sois particulièrement attentifs aux pointeurs qui sont référencés par différents éléments... On a vite fait "d'oublier" de mettre l'un des éléments à jour pour indiquer que le pointeur en question a été détruit ou qu'il a "changé de place".
    6. Sépare très clairement la responsabilité qui permet l'utilisation de tes pointeurs de celle qui en permet le maintien. Pas seulement au niveau des fonctions, mais carrément au niveau de classes (ou de structures) différentes : le terme générique "manager" est une catastrophe pour le SRP
    7. J'en oublie surement, mais commence déjà par cela
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Segmentation fault incomprehensible
    Par sorry60 dans le forum Réseau
    Réponses: 12
    Dernier message: 10/12/2005, 17h06
  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