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 aprés migration


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 51
    Points : 36
    Points
    36
    Par défaut Crash aprés migration
    Bonjour

    Aprés une migration de Visual 2005 vers Visual 2008 ,j'ai pas mal de crash car le comportement du compilateur a changé , ce genre de code simplifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          BYTE * pBLOB = new BYTE[5*sizeof(std::vector <int *>)];
          memset(pBLOB,0,5*sizeof(std::vector <int *>));
          std::vector<int *> *sv = (std::vector <int *> *)pBLOB;
          sv->clear();
    ça crashe en Release Visual 2008 mais pas en Visual 2003 .

    C'est un exemple simplifié car y en a beaucoup d'autres et ce sera très difficile de cerner tous les bouts de codes qui risquent de causer un crash .

    Y a t il quelqu'un qui a une idée sur une solution (paramétres de compil ..)?

  2. #2
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par capello123 Voir le message
    Bonjour

    Aprés une migration de Visual 2005 vers Visual 2008 ,j'ai pas mal de crash car le comportement du compilateur a changé , ce genre de code simplifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          BYTE * pBLOB = new BYTE[5*sizeof(std::vector <int *>)];
          memset(pBLOB,0,5*sizeof(std::vector <int *>));
          std::vector<int *> *sv = (std::vector <int *> *)pBLOB;
          sv->clear();
    ça crashe en Release Visual 2008 mais pas en Visual 2003 .

    C'est un exemple simplifié car y en a beaucoup d'autres et ce sera très difficile de cerner tous les bouts de codes qui risquent de causer un crash .

    Y a t il quelqu'un qui a une idée sur une solution (paramétres de compil ..)?
    Hello,

    Quelques questions:
    Pourquoi faire quelques chose comme ça, quand on peut faire simplement un std::vector<int*> sv; pour arriver au même résultat ?

    Pourquoi 5*sizeof(std::vector<int*>) ?

    Sinon le problème vient du fait que ton vector n'est pas construit. Dans ton cas il faut utiliser un placement new et pas un cast (pour l'appel au constructeur)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    BYTE * pBLOB = new BYTE[sizeof(std::vector <int *>)];
    std::vector<int *> *sv = new(pBLOB) std::vector <int *>;

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 51
    Points : 36
    Points
    36
    Par défaut
    Ce que j'ai posté est un exemple simplifié de ce qu'on a dans le code. Ce qui fait crasher en gros c'est de faire un clear() sur vecteur vide, alors que ça passait sur du Visual 2003.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Euh, avec un code pareil, la première réponse qui me vient est...

    Bien fait pour vous !

    Plusieurs mauvaise pratique en C++ : l'utilisation des pointeurs nus, déréférencer un pointeur sans testé s'il est null avant, des cast bourrins, de memset...

    Vous créer un tableau avec new[] de BYTE (c'est quoi ?), vous remplissez la mémoire avec des 0, vous caster ensuite en pointeur vers un vector<int*>, puis vous essayer de l'utiliser comme si tout aller bien...

    Le problème n'est pas le compilateur (je crois), je pense plutôt à un comportement indéterminé (dans le norme) qui tombait en marche sur VS 2003 et plus sous VS 2008 (euh, au fait, on est en 2013...) Ou peut être que la norme à changée. Ou VS est devenu plus respectueux de la norme.

    Bref, code à virer et à changer par du code propre.
    Le but de ce code est de faire quoi ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 51
    Points : 36
    Points
    36
    Par défaut
    Ce code a été simplifié et isolé pour voir le bout de code qui crash. C'est une grosse application développée depuis des années. Le problème, c'est qu'on ne peut pas virer tout et refaire car c'est énorme... que du bricolage :/

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    De loin ça me fait vaguement penser à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<int*> aVec = new std::vector<int*>[5];
    std::vector<int*>* sv = &(aVec[0]);
    Mais ce que je trouve le plus suspect, ça reste le memset, et je ne vois pas où le constructeur est appelé

    Ce code a été simplifié et isolé pour voir le bout de code qui crash. C'est une grosse application développée depuis des années. Le problème, c'est qu'on ne peut pas virer tout et refaire car c'est énorme... que du bricolage :/
    Bienvenue en France, le paradis de la dette technique où "ça marchait avant" !
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    @Bousk
    Jamais Mais de toute façon avec un memset(0), le tableau contient que des null, faire un accès est... "moyen"

    @capello123
    Au choix :
    - rester sous VS 2003
    - chercher une option de compilation qui autorise ce genre d'erreur (je suis pas spécialiste de VS, je peux pas t'aider là, faire une recherche sur msdn)
    - corriger le code pour ajouter des if(vs) vs->clear(); (en espérant que tous vos pointeurs soient correctement à null)
    - corriger le code pour écrire du code propre

    Bon courage

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 51
    Points : 36
    Points
    36
    Par défaut
    Merci pour vos réponses .

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Effectivement le code original joue avec le feu...

    Il part du principe que l'on peut économiser l'appel au constructeur de std::vector<T> en mettant à zéro une zone de mémoire de taille sizeof(std::vector<T>) puis en castant un pointeur vers le début de la zone en std::vector<T>*.

    Le pire c'est que c'est effectivement vrai dans la plupart des implémentations de std::vector qui se base sur 3 pointeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template <typename T>
    class vector
    {
       T* _first;
       T* _last;
       T* _end;
    };
    Dans ce cas un memset(&v, 0, sizeof(std::vector<T>)) viendra mettre les trois pointeurs à NULL ce qui est exactement ce qui fait le constructeur par défaut de std::vector<T> dans la plupart des cas.

    Manque de bol il semblerait que l'implémentation de std::vector ait suffisamment changé entre vs2003 et vs2008 pour que l'astuce assez affreuse du memset ne soit plus valide...

    Pour s'assurer d'un code correct la seule solution me semble de faire des placement new comme préconisé par Iradrille plus haut.

  10. #10
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Effectivement, j'avais pas compris l'idée derrière. L'objectif est plus clair

    Par contre, sauf contexte très très particulier, c'est vraiment un hack moisi (idem pour le placement new). Perso, je dégagerais ça pour utiliser un simple tableau statique ou un vector

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<vector<int*>> sv(5);
    vector<int*> sv[5];
    voir un simple vector<in*> contenant la totalité des 5 tableaux (différence de performance qui peut être négligeable, en fonction des redimensionnement effectuées, de la taille des tableaux et du système)

    Rien que pour le fait que tout le monde ne comprend pas ce code (évolutivité moisie) et que c'est pas résistant au bugs (maintenance moisie)

Discussions similaires

  1. Crash base de données après migration serveur
    Par theophile76 dans le forum Installation
    Réponses: 0
    Dernier message: 05/12/2013, 09h07
  2. Format date dans état après migration
    Par guiguikawa dans le forum Access
    Réponses: 10
    Dernier message: 21/06/2006, 13h27
  3. make-kpkg HS après migration sarge-etch
    Par le mage tophinus dans le forum Debian
    Réponses: 4
    Dernier message: 18/04/2006, 07h21
  4. PB Rowid après migration Oracle7 à 9i
    Par Chonchon dans le forum Bases de données
    Réponses: 4
    Dernier message: 23/02/2006, 13h20
  5. [IB6] mon serveur crash apres des insert en série...
    Par Rmotte dans le forum Débuter
    Réponses: 11
    Dernier message: 27/05/2004, 14h53

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