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 :

Mode debug différent de mode release - sprintf pas effectué à temps


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2022
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2022
    Messages : 34
    Par défaut Mode debug différent de mode release - sprintf pas effectué à temps
    Bonjour tout le monde,

    J'ai encore une bizarrerie :
    - Lorsque j'exécute un code en mode release, il n'y a pas de problème.
    - Lorsque j'exécute le même code en mode debug en ne mettant pas trop de points d'arrêts, il n'y a pas de problème.
    - Lorsque j'exécute le même code en mode debug en ne mettant des points d'arrêts juste avant le sprintf() et juste après et encore juste après, il y a un problème.
    Le problème est soit que le sprintf n'est pas effectué, soit que l'ordi tourne à fond, soit qu'il plante.

    J'ai trouvé une solution. J'ai décomposé ma fonction en 3 fonctions et cela ne me paraît plus poser plus de problèmes. Mais j'ai voulu comprendre. J'ai alors dupliqué la fonction qui posait problème et j'ai enlevé tout ce qui ne posait pas de problème. Il reste le code suivant. Si on met des points d'arrêts partout, le programme a beaucoup de mal à passer d'un point d'arrêt à l'autre.

    Il suffit de changer long long int en int, ou supprimer n'importe quelle ligne de code ou remplacer les variables par leurs valeurs pour que ça fonctionne.
    Il met une trentaine de secondes à chaque étape et surtout, lorsqu'il s'est enfin arrêté au point d'arrêt après le sprintf, il n'a pas exécuté l'instruction ; il faut encore attendre pour que l'instruction soit prise en compte (alors qu'il est déjà arrêté au point d'arrêt).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    void test(const char* string1)
    {
      long long int  k,s,cnt,beg,end,op,s1,s1E;
      char*          ptr;
      char*          string2 = new char[100];
     
      sprintf(string2,"diff(%s)",string1);
      k   = 0;
      s   = 0;
      cnt = 0;
      beg = 5;
      end = 0;
      op  = 0;
      s1  = 13;
      s1E = 11;
      ptr = NULL;
      char op1 [s1 ]; memcpy(op1 ,&string2[beg]  ,s1 -1);
      char op1E[s1E]; memcpy(op1E,&op1[s1 != s1E],s1E-1);
    }
     
    int main(int argc, char *argv[])
    {
      test("12345678*123456");
      return 1;
    }
    Quelqu'un a-t-il déjà connu ce genre de problème svp ?

    Merci à tous qui lisez mes messages et qui y répondez, sachant que je suis le seul à poser des questions...

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Bonjour,

    Pourquoi n'utilisez vous pas la gestion automatique de la mémoire (intérêt de faire du C++)

    En C++ on pourrait avoir un code ressemblant à,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cstring>  // Pour memcpy
     
    void test(const std::string& string1)
    {
        long long int beg, s1, s1E;
        std::string string2 = "diff(" + string1 + ")";
     
        beg = 5;
        s1  = 13;
        s1E = 11;
     
        std::string op1 = string2.substr(beg, s1 - 1);
        std::vector<char> op1E(s1E);
        memcpy(op1E.data(), &op1[s1 != s1E], s1E - 1);
        op1E[s1E - 1] = '\0';  // Ajout d'un null-terminator pour éviter les problèmes d'affichage.
     
        std::cout << "op1: " << op1 << std::endl;
        std::cout << "op1E: " << op1E.data() << std::endl;
    }
     
    int main()
    {
        test("12345678*123456");
        return 0;
    }
    avec un résultat (ce qui ne semble pas être le cas chez vous)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fred1599@PC-Fred ~ $ ./my_program
    op1: 12345678*123
    op1E: 2345678*12
    On pourrait ensuite avantageusement transformer en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <iostream>
    #include <string>
     
    void test(const std::string& string1)
    {
        long long int beg = 5, s1 = 13, s1E = 11;
        std::string string2 = "diff(" + string1 + ")";
     
        // Utilisation de substr pour éviter memcpy
        std::string op1 = string2.substr(beg, s1 - 1);
        std::string op1E = op1.substr(s1 != s1E ? 1 : 0, s1E - 1);
     
        std::cout << "op1: " << op1 << std::endl;
        std::cout << "op1E: " << op1E << std::endl;
    }
     
    int main()
    {
        test("12345678*123456");
        return 0;
     
    }

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 502
    Par défaut
    Je plussois la réponse de @fred1599.
    Le problème est soit que le sprintf n'est pas effectué, soit que l'ordi tourne à fond, soit qu'il plante.
    Vous utilisez quoi comme débogueur ?
    Généralement, c'est pas le débogueur le problème.
    En mode DEBUG, généralement, il n'y a pas d'optimisation, rendant le code "plus" stable qu'il ne le serait en mode RELEASE.
    Mais il y a des réglages par défaut en DEBUG qui permettent de systématiquement détecter des conneries de développement.
    DEBUG est donc aussi plus "stable" dans les "plantages" (éviter les "heisenbugs")

    Mais tout ceci, c'est si vous utilisez une chaine de compilation et un débogueur "moderne".

    Votre code est blindé de "conneries" (des choses à ne pas faire) en C++. C'est quoi votre niveau de Warning ? Avez-vous bien tenu compte des warning du compilateur et de l'éditeur de lien ?

    Il suffit de changer long long int en int, ou supprimer n'importe quelle ligne de code ou remplacer les variables par leurs valeurs pour que ça fonctionne.
    Cela déclenche mon biais à faire des corrélations abusives mais je sens que l'utilisation des VLA dans votre code, qui n'ont jamais été supportés en C++ et que brièvement en C, n'est pas étrangère à vos problèmes.
    Lisez et comprenez les warning (et activez leur niveau maximum).

    Il met une trentaine de secondes à chaque étape et surtout, lorsqu'il s'est enfin arrêté au point d'arrêt après le sprintf, il n'a pas exécuté l'instruction ; il faut encore attendre pour que l'instruction soit prise en compte (alors qu'il est déjà arrêté au point d'arrêt).
    Un classique de ce genre de truc, c'est que les variables soient "correctement" initialisées avec du "FBADBEEF" qui entraine une grande taille d'allocation => temps énorme pour que l'OS trouve la place nécessaire, puis le débogueur qui perd ses petits parce que cela prend trop de temps, que des éléments de validations DEBUG soient énormes ou écrasées. Et un débogueur n'est jamais un outil "temps réel", surtout si on lui file un code foireux (non standard) dans les pattes.

    Des librairies de manipulations, mise en forme, etc... de chaines de caractères, en C++, il y en a par dizaines, si ce que fourni le standard C++ ne suffirait pas.

    Quelqu'un a-t-il déjà connu ce genre de problème svp ?
    Oui, et les warning m'ont ouvert les yeux.

  4. #4
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2022
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2022
    Messages : 34
    Par défaut
    Bonjour et merci pour vos réponses.

    Je ne sais pas ce que j'utilise comme débogueur ; je travaille sous Qt Creator. Je ne sais pas comment faire pour toucher le makefile. J'appuie sur F5 pour lancer le débogueur. Les processus suivants tournent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Nom de l'image		Processeur	Mémoire
    gdb.exe *32		00 %		488 K
    gdborig.exe *32		48 %		112 368 K
    qtcreator.exe *32	01 %		128 276 K
    Mon code est blindé de conneries ? Là, il est correct ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    void test(const char* string1)
    {
      long long int  k,s,cnt,beg,end,op,s1,s1E;
      char*          ptr;
      char*          string2 = new char[100];
     
      if (sprintf(string2,"diff(%s)",string1) != -1)
      {
        k   = 0LL;
        s   = 0LL;
        cnt = 0LL;
        beg = 5LL;
        end = 0LL;
        op  = 0LL;
        s1  = 13LL;
        s1E = 11LL;
        ptr = NULL;
        char op1 [s1 ]; memcpy(op1 ,&string2[beg]  ,s1 -1);
        char op1E[s1E]; memcpy(op1E,&op1[s1 != s1E],s1E-1);
      }
      delete [] string2;
    }
     
    int main(int argc, char *argv[])
    {
      test("12345678*123456");
      return 0;
    }
    Je ne sais pas c'est quoi mon niveau de warning, les warning sont indiqués ci-dessous.
    Comment activer le niveau maximum de warning svp ?
    Pour les VLA, c'est très mal vu, mais puisque c'est possible, c'est qu'on doit pouvoir les utiliser.

    Je n'ai pas trouvé sur internet ce que FBADBEEF est.
    Je n'ai pas trop compris ce paragraphe, surtout la phrase << puis le débogueur qui perd ses petits parce que cela prend trop de temps, que des éléments de validations DEBUG soient énormes ou écrasées >>.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    12:53:45: Exécution des étapes pour le projet Test...
    12:53:45: Configuration inchangée, étape qmake sautée.
    12:53:45: Débute : "C:\Qt\Qt5.4.1\Tools\mingw491_32\bin\mingw32-make.exe" 
    C:/Qt/Qt5.4.1/Tools/mingw491_32/bin/mingw32-make -f Makefile.Debug
    mingw32-make[1]: Entering directory 'E:/Nouveau/Science/build-Test-Desktop_Qt_5_4_1_MinGW_32bit-Debug'
    g++ -c -pipe -fno-keep-inline-dllexport -std=c++11 -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_CORE_LIB -I"..\Z0\Test" -I"." -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include\QtCore" -I"debug" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\mkspecs\win32-g++"  -o debug\misc.o ..\Z0\Graph\misc.cpp
    g++ -c -pipe -fno-keep-inline-dllexport -std=c++11 -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_CORE_LIB -I"..\Z0\Test" -I"." -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include\QtCore" -I"debug" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\mkspecs\win32-g++"  -o debug\draw.o ..\Z0\Graph\draw.cpp
    g++ -c -pipe -fno-keep-inline-dllexport -std=c++11 -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_CORE_LIB -I"..\Z0\Test" -I"." -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include\QtCore" -I"debug" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\mkspecs\win32-g++"  -o debug\graph.o ..\Z0\Graph\graph.cpp
    g++ -c -pipe -fno-keep-inline-dllexport -std=c++11 -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_CORE_LIB -I"..\Z0\Test" -I"." -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include\QtCore" -I"debug" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\mkspecs\win32-g++"  -o debug\string.o ..\Z0\Graph\string.cpp
    g++ -c -pipe -fno-keep-inline-dllexport -std=c++11 -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_CORE_LIB -I"..\Z0\Test" -I"." -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\include\QtCore" -I"debug" -I"C:\Qt\Qt5.4.1\5.4\mingw491_32\mkspecs\win32-g++"  -o debug\main.o ..\Z0\Test\main.cpp
    ..\Z0\Test\main.cpp: In function 'void test(const char*)':
    ..\Z0\Test\main.cpp:14:18: warning: variable 'k' set but not used [-Wunused-but-set-variable]
       long long int  k,s,cnt,beg,end,op,s1,s1E;
                      ^
    ..\Z0\Test\main.cpp:14:20: warning: variable 's' set but not used [-Wunused-but-set-variable]
       long long int  k,s,cnt,beg,end,op,s1,s1E;
                        ^
    ..\Z0\Test\main.cpp:14:22: warning: variable 'cnt' set but not used [-Wunused-but-set-variable]
       long long int  k,s,cnt,beg,end,op,s1,s1E;
                          ^
    ..\Z0\Test\main.cpp:14:30: warning: variable 'end' set but not used [-Wunused-but-set-variable]
       long long int  k,s,cnt,beg,end,op,s1,s1E;
                                  ^
    ..\Z0\Test\main.cpp:14:34: warning: variable 'op' set but not used [-Wunused-but-set-variable]
       long long int  k,s,cnt,beg,end,op,s1,s1E;
                                      ^
    ..\Z0\Test\main.cpp:15:18: warning: variable 'ptr' set but not used [-Wunused-but-set-variable]
       char*          ptr;
                      ^
    g++ -Wl,-subsystem,console -mthreads -o debug\Test.exe debug/misc.o debug/draw.o debug/graph.o debug/string.o debug/main.o  -LC:/Qt/Qt5.4.1/5.4/mingw491_32/lib -lQt5Cored 
    mingw32-make[1]: Leaving directory 'E:/Nouveau/Science/build-Test-Desktop_Qt_5_4_1_MinGW_32bit-Debug'
    12:53:57: Le processus "C:\Qt\Qt5.4.1\Tools\mingw491_32\bin\mingw32-make.exe" s'est terminé normalement.
    12:53:57: Temps écoulé : 00:12.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut
    Salut,

    Premier point, ton code n'est pas du C++.

    Ensuite, qu'entends-tu par "il y a un problème" ?

    Garde bien en tête qu'en mode debug, l'exécutable est généré avec les informations de debug, pour permettre l'observation des variables, l'execution en pas à pas, les points d'arrêt ect ..., il suffit de comparer la taille des éxécutables générés pour s'en rendre compte.
    L'environnement d'exécution est également complètement diffèrent.

    Donc il est possible qu'une anomalie subordonnée au mode Debug soit un faux positif.

    Le mieux est encore de faire tourner des tests unitaires.

  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2022
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2022
    Messages : 34
    Par défaut
    Bonjour et merci.

    J'avais mal tapé le message initial, je l'ai corrigé. De plus, j'avais tapé
    Le problème est soit que le sprintf n'est pas effectué, soit que l'ordi tourne à fond, soit qu'il plante.
    , mais il est possible que le plantage soit dû à une autre erreur.

    Donc, le problème est que, si je mets des points d'arrêts en début de chaque ligne :
    - On passe du point d'arrêt juste avant le sprintf au point d'arrêt juste après le sprintf au bout de 20 secondes.
    - L'affichage de string2 a lieu encore 30 secondes après l'exécution du sprintf.
    - De même, l'affichage des variables a lieu 30 secondes après l'exécution de chaque instruction suivante. (Et si je veux passer au point d'arrêt suivant sans attendre l'affichage, il mettra alors 30 secondes avant d'effectuer l'instruction).

    Premier point, ton code n'est pas du C++.
    J'ai posté mon message ici car lorsque je poste sur le forum C, on me dit qu'il faut poster le message sur le forum C++.

    Donc il est possible qu'une anomalie subordonnée au mode Debug soit un faux positif.
    Oui, c'est ce que je vais me dire.
    Et je prends en compte
    l'utilisation des VLA dans votre code, qui n'ont jamais été supportés en C++ et que brièvement en C, n'est pas étrangère à vos problèmes
    .

    Merci aussi de me conseiller d'utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include <string>
    #include <vector>
    , il faudra que je m'y mette.

    Par exemple, si j'enlève la ligne , le programme plante et affiche 2 petites fenêtres :
    Le processus gdb s'est arrêté de façon inattendue (code 3).
    Windows recherche une solution au problème.

Discussions similaires

  1. Réponses: 3
    Dernier message: 19/07/2022, 09h32
  2. Erreur en mode Release mais pas en mode Debug
    Par ypelissier dans le forum C#
    Réponses: 2
    Dernier message: 21/03/2022, 12h07
  3. [c#] Mode debug / mode release
    Par benzouille dans le forum Windows Forms
    Réponses: 1
    Dernier message: 14/04/2006, 13h19
  4. Pas d'appel à une fonction si mode Release
    Par Crisanar dans le forum C++
    Réponses: 8
    Dernier message: 17/09/2005, 04h54
  5. Réponses: 11
    Dernier message: 09/07/2005, 08h47

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