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 :

crash en release, comment detecter l'erreur?


Sujet :

C++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut crash en release, comment detecter l'erreur?
    Bonjour à tous,

    je travaille sur un gros projet, qui est un affreux mélange de C et de C++. En debug, ça fonctionne bien. Mais en release, j'ai un crash très étrange et je ne parviens pas à détecter l'erreur.

    Je suis parvenu à trouver l'endroit ou ça plante, mais je n'arrive pas à trouver pourquoi ça plante. C'est dans une grosse fonction (une quarantaine de lignes). Si dans la fonction, j'ajoute une ligne qui alloue de la mémoire (par exemple un vector), ça plante à la fin du bloc.

    Par exemple, si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //code
    {
    	std::cout << " *** 1 *** " << std::endl;
    	vector<int> dum_vect( 520 );
    	std::cout << " *** 2 *** " << std::endl;
    }
     
    std::cout << " *** 3 *** " << std::endl;
    //code
    la sortie donne:
    *** 1 ***
    *** 2 ***
    <crash>
    si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //code
    std::cout << " *** 1 *** " << std::endl;
    vector<int> dum_vect( 520 );
    std::cout << " *** 2 *** " << std::endl;
     
    //code
    la sortie donne
    *** 1 ***
    *** 2 ***
    <crash à la sortie du bloc suivant>
    Ca m'a tout l'air d'être une corruption de la pile, mais comment trouver quel est le code qui corrompt la pile? Le problème est que cette fonction utilise des tableaux "c-style" de types complexes, et si je dois vérifier tout j'en ai pour une semaine au moins. Et quel que soit l'endroit où je place mon allocation, le crash survient toujours à la sortie du bloc.

    Je suis sous windows XP, avec visual 2008 pro SP1. Connaissez-vous des outils, des astuces, pour m'aider à trouver à quel endroit la pile est corrompue?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Regarde du côté de GFlags.

    Une recherche sur le nom sur msdn devrait te donner des résultats. Aussi, avec windbg, tu as plus d'options pour détecter ce genre d'erreurs.

    Bon courage et bonne lecture, les gflags sont loin d'être simple d'utilisation .

  3. #3
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    A part que le code généré est plus rapide, le fait que les variables ne soient pas initialisées à 0 en mode release est la seule différence que je connaisse avec le mode debug.
    Ca vaut peut-être le coup de vérifier si les variables qui doivent l'être, sont bien initialisées à zéro, sinon tu te retrouves avec une différence de comportement.

    Mais, c'est peut-être pas ça...

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Tu as plus de chance que moi

    Je pense au simple stack overflow.

    Je pense aussi à des "mélanges" de pragma pack(), par exemple une librairie ou un fichier cpp compilé en pragma pack(1) et le reste en pragma pack(8) (mais qui aurait bien pu changer ces options entre les modes Debug et Release, d'une librairie/cpp à l'autre ?).

    Désactive les optimisatons qui ne sont pas celles par défaut en mode Release (les compilos générent parfois du code machine erroné...)

    Compare ainsi les options de compilation entre les deux modes, les #define surtout.

    Utilisation d'une instruction MMX/SSE ou autre non disponible sur la machine d'éxecution...

    Etc.

    Mais bon, le plus probable reste un erreur de programmation logique.

  5. #5
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Re,

    j'ai enfin trouvé l'erreur! Ca ressemble à du sabotage
    voyez:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void func1( float* f_vector, int f_size )
    {
    // code...
    	func2( &f_vector[1], 0, f_size ); // remplacé par func2( f_vector, 0, f_size ) et ça marche
    // code...
    }
     
    void func2(float* values, unsigned pos, unsigned sizeVal)
    {	
    	memcpy(&m_values[pos], values, sizeof(float)*sizeVal);
    }
    Mais je ne parviens pas à conprendre pourquoi ça ne plantait pas en mode debug. Sur [ame=http://www.codeguru.com/forum/showthread.php?t=269905]cette page[/ame] on voit bien que la seule différence est, comme dit Charlemagne, l'intialisation des variables. Cet article est un peu vieux, mais je ne pense pas qu'il y ait d'autres différences.

    Je viens de tester en mode release avec le flag _DEBUG, et ça plante aussi.
    Comprends pô

    edit:
    Waahh, j'ai trouvé. La réponse ici, si ça intéresse quelqu'un. c'est ce qu'ils appellent une "bound error"

    merci à tous pour votre aide
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Avec cette fonction et le flag _CRTDBG_CHECK_ALWAYS_DF, tu aurais eu une erreur en Debug lors du delete/free, voire même de ton prochain new/malloc.

    Par contre, ça plombe les performances comme c'est pas permis, même par rapport à un Debug "normal".
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    screetch
    Invité(e)
    Par défaut
    ce flag est activable a la volée cependant. Ou sinon, appeler manuellement CrtCheckMemory aux alentours du code suspect permet de ne pas plomber les perfs.

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

Discussions similaires

  1. comment detecter les erreur de gestion memoire
    Par adel25 dans le forum Langage
    Réponses: 2
    Dernier message: 29/12/2009, 23h45
  2. Comment résoudre l'erreur : "table marquée crashed" ?
    Par bigsister dans le forum Requêtes
    Réponses: 15
    Dernier message: 21/01/2008, 13h20
  3. Réponses: 4
    Dernier message: 23/08/2006, 14h15
  4. Comment detecter un polygon sous le curseur
    Par FreshVic dans le forum OpenGL
    Réponses: 2
    Dernier message: 04/07/2003, 10h48
  5. Comment detecter le type d'un objet?
    Par nickylarson dans le forum C++Builder
    Réponses: 3
    Dernier message: 24/06/2003, 15h23

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