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 :

Obtenir le nom d'une fonction à partir de son addresse (pointeur fonction)


Sujet :

C

  1. #1
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut Obtenir le nom d'une fonction à partir de son addresse (pointeur fonction)
    Bonjour à tous,

    J'ai passé quelques heures à essayer de trouver une solution pour obtenir le nom des fonctions à partir de leur pointeur.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void toto()
    {
    }
     
    int main()
    {
    // pointeur de fonction sur toto()
    void (*PtrToto)();
    ptrToto = toto;
    PtrToto();
    }
    Je voudrais grâce à PtrToto (disons que l'adresse mémoire est 0xABCDEF) pourvoir récupérer le vrai nom de la fonction pointée à savoir "toto" sous forme de chaine de caractères.

    Sous Linux, j'ai trouvé des solutions en activant l'option -g pour avoir les symboles de debug. Pour les intéressés, la solution est ici :
    http://stackoverflow.com/questions/3...s-pointer-in-c

    Mais sous Windows, je n'ai trouvé que ce lien :
    http://ivbel.blogspot.fr/2012/02/how...name-from.html

    Le problème est que la fonction SymGetSymFromAddr64 me renvoie toujours l'erreur 487 (Attempt to access invalid address. ).
    Pourtant j'ai bien mis l'option -g de GCC pour inclure les symboles de debug.

    A mon avis, je dois mal appeler la fonction puisque j'ai une erreur de compilation quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TRACE_POINTER(myfunction); // macro issue du code du lien ci-haut
    Voilà mon code :
    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
     
    // le code du lien plus haut dont les deux macros
    #define TRACE_POINTER_INIT InitDebug()
    #define TRACE_POINTER(f) TracePointerInfo((DWORD64)(f))
     
    void toto()
    {
     
    }
     
    int main()
    {
        void (*ptrToto)();
     
        TRACE_POINTER_INIT; // INIT OK
     
        ptrToto = toto;
     
        ptrToto(); // appel de la fonction
     
        TRACE_POINTER(ptrToto); // compile pas ici
        TRACE_POINTER((int)ptrToto); // compile mais erreur 487 
     
        return 0;
    }
    L'erreur est :
    main.c|137|attention : transtypage d'un pointeur vers un entier de taille différente [-Wpointer-to-int-cast]
    Et ca vient du cast en DWORD64. Il doit y avoir une perte de précision où je en sais quoi et du coup l’adresse est invalide... Si je force un cast en int ca compile mais la fonction SymGetSymFromAddr64 retourne l'erreur 487.

    Voilà, j'ai rien trouvé sur le net et je suis bien embêté.

    Merci à vous.

    PS : Je travaille sous Windows 7 64 bits.
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 377
    Points : 23 656
    Points
    23 656
    Par défaut
    Bonjour,

    Si je suis le lien que tu nous donnes, je lis :

    Possible problems and how to fix them:
    1. SymGetSymFromAddr64 fails, last error is 487 (Attempt to access invalid address. ). Answer: most likely debug information is not found. Rebuild the project for Debug.

    2. SymGetSymFromAddr64 fails, last error is 6 (The handle is invalid). Answer: most likely SymInitialize was not called.

    Cela dit, peut-on savoir pourquoi tu cherches à faire cela ?

  3. #3
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    J'ai bien inclus les symboles de Debug (option -g de GCC) et je suis bien en Debug...

    Je cherche à faire un profiler "à la main" afin de mesurer entre autre le temps d’exécution des fonctions.
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  4. #4
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par Aspic Voir le message
    J'ai bien inclus les symboles de Debug (option -g de GCC) et je suis bien en Debug...

    Je cherche à faire un profiler "à la main" afin de mesurer entre autre le temps d’exécution des fonctions.
    Salut,

    cela pourrait (je n'en suis pas certain du tout) provenir du fait que gcc avec l'option -g ne génère pas les info de debuging au bon format. En fait il existe différents formats (COFF,XCOFF,DWARF,DWARF2,PDB, sans doute bien d'autres). L'API que tu utilises (DbgHelp) doit utiliser le format PDB (propriétaire microsoft?) alors que l'option -g doit insérer un autre format. Tu peux dire à gcc de changer le format des info de debug mais PDB n'est pas dispo. En lisant en diagonale sur le net il se peut que DbgHelp accepte le COFF ... ça vaut le coup d'essayer avec l'option -gcoff ou -gxcoff.

    références : MSDN (vieux), les options debug de gcc.

    Quelle est ta chaîne de compilation ?

  5. #5
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Salut,

    C'est une bonne remarque, oui dbghelp est utilisé à la base sous Visual Studio et les fichiers de symboles sont bien des PDB.

    J'ai du faire une manipulation sur ce lien pour générer une librairie .a compatible GCC à partir d'un fichier lib (provenant de VS) :
    http://stackoverflow.com/questions/1...ltool-of-mingw

    La commande que j'ai faite est :
    dlltool -k -d libdbghelp.def -l dbghelp.a
    Après, pour l'instant, j'utilise CodeBlocks avec MinGW en rajoutant les options de compilation à la main pour faire mes tests.
    J'ai testé avec -gcoff mais même résultat.

    Je me demande si c'est pas simplement le cast qui plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TRACE_POINTER((int)ptrToto);
    Après tout la fonction attend un DWORD64 et non un INT.
    Et sans le cast, ca compile pas.
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  6. #6
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Après quelques heures de recherche, je n'ai trouvé que cela :
    http://mingw32dbghelp.sourceforge.net/

    Apparemment on pourrait recompiler dbghelp pour l'utiliser avec GCC et utiliser les symboles dwarf2 pour faire ce que je veux mais je n'arrive pas à compiler la librairie

    Si quelqu'un pouvait essayer de me compiler la librairie et de me donner les binaires, ca serait cool (fichiers .a, .dll).

    Bon pour ce soir, je laisse tomber les recherches...

    PS : le code ci-haut fonctionne sous Visual Studio avec des fichiers PDB, ca m'étonne pas c'est une API à la Microsoft bien propriétaire

    Bonne soirée
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  7. #7
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    En jetant un coup d’œil aux liens que tu donnes je me dis que ça fait un peu usine à gaz, surtout si tu commences à remplacer ou bypasser des dll système ...
    Je me demande s'il ne serait carrément plus simple pour toi d'installer dans un coin linux et d'utiliser wine (qui aura par défaut la bonne dll dbghelp) pour tes tests. Mais du coup certaines données pourraient être faussées (linux+wine ne doit pas avoir les mêmes stratégies d'allocation de mémoire que win7 par exemple) et d'autres pas (savoir si toute la mémoire allouée est bien libérée est indépendant de la stratégie d'allocation par exemple) quant aux temps d'exécution on ne peut même pas dire s'ils seront meilleurs ou pires.

    Juste pour me remettre ton problème en tête ... tu as des élèves qui te donnent leurs sources (eux développent avec msvc) et tu désires tout recompiler avec un makefile qui gère les dépendances en utilisant mingw, tout ça en rajoutant des checks pour vérifier qu'il n'y a pas de fuites mémoires ... c'est ça ?

  8. #8
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Je ne suis pas contre installer un Linux (j'ai déjà un Ubuntu) mais je n'y connait pas grand chose en Linux et encore moins avec Wine.

    Citation Envoyé par kwariz Voir le message
    Juste pour me remettre ton problème en tête ... tu as des élèves qui te donnent leurs sources (eux développent avec msvc) et tu désires tout recompiler avec un makefile qui gère les dépendances en utilisant mingw, tout ça en rajoutant des checks pour vérifier qu'il n'y a pas de fuites mémoires ... c'est ça ?
    C'est exactement cela sauf que tous mes élèves développent sous CodeBlocks avec Mingw comme compilateur.
    Et ils sont tous sous Windows 7 ou 8 pour le développement (les sources pour Linux ne sont pas autorisées).

    Et ce que j'essaye en ce moment c'est de profiler les fonctions grâce à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void __cyg_profile_func_enter(void *this_fn, void *call_site)
    void __cyg_profile_func_exit(void *this_fn, void *call_site)
    Mais avec les adresses des fonctions ce n'est pas parlant du tout d'où l'idée de remplacer ces adresses par des noms "human readable"
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  9. #9
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Avec un environnement mingw tu peux passer l'option -pg à gcc lors de la compilation et de l'édition des liens. Ensuite tu lances le programmes qui te génère un fichier qui contient pas mal de données (nombre d'appel, % du temps passé dans un fonction, etc ...) : cela pourrait peut-être convenir et t'éviterait un trop grand investissement en compilation de dll ...
    Quant à la vérification des fuites mémoires, ta solution de «surcharge de malloc» convient, non ?

  10. #10
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Oui je connaissais l'option -pg il y a un moment.
    Ca se lit bien avec Gprof ? Ca serait possible de récupérer le nom des fonctions et leur temps d’exécution avec -pg ? D'après mes souvenirs, je n'avais pas réussi à utiliser gprof (ou alors les rapports étaient illisibles...)

    Sinon oui, le programme de check des fuites de mémoire me convient parfaitement (même si ca ne vaut pas du tout un valgrind) mais pour ce que je veux en faire en terme d'apprentissage pédagogique, ca me suffit amplement
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  11. #11
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Oui, il faut gprof (je suppose qu'il est disponible dans la distribution mingw). C'est vrai que parfois ça donne des fichiers un peu fouillis, mais ça se paramétrise avec les options que tu files à gprof. Il y a aussi avec les options gcc -fprofile-arcs et -ftest-coverage et l'outil gcov la possibilité d'annoter les sources avec des stats.
    Fait quelques tests pour voir si ça peut t'être utile.

  12. #12
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    J'ai regardé gprof de plus près, effectivement on peut avoir des infos pratiques mais le parsage des fichiers de sortie n'est pas facile

    gcov à l'air pas mal mais j'ai pas trop compris comment ca marche ce truc
    En fait, j'ai bien ajouté les options à gcc et au linker j'ai pris la librairie libgconv.a
    Pour chaque fichier objet (.o), j'ai un fichier .gcno qui se créé.
    Et quand je lance le programme, j'ai pour chaque fichier objet, un fichier .gcda qui se créé. Donc pour un main.c -> main.o -> main.gcno -> main.gcda

    J'ai donc testé de passer ces fichiers dans gconv :
    gconv main.gcno -f // par exemple
    gconv main.gcda -f // semble marcher aussi
    gconv main.o -f // semble marcher aussi
    gconv main.c -f // et même ca !
    Et ca me créé un fichier .c.gcov (à mon avis ca donne les parties de code jamais exécutée). C'est bizarre que ca accepte n'importe quel type de fichier en entrée...

    Donc je me demande en fait, à quoi sert tout ces fichiers et quelle est la vraie commande à exécuter disons pour récupérer toutes les fonctions d'un programme (option -f je crois d'après la pseudo doc) et leur temps moyen d’exécution ?
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  13. #13
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Pour illustrer mes propos j'ai juste construit un programme un peu bidon, je joins les sources.
    Pour avoir l'information profilage (temps passé dans une fonction, temps moyen d'exécution de la fonction) : gprof -p = flat profile
    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
    34
    35
    > gprof -p test 
    Flat profile:
     
    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls  ms/call  ms/call  name    
     90.88      4.44     4.44      189    23.47    23.47  syracuse
      9.23      4.89     0.45       19    23.71   257.13  distance
     
     %         the percentage of the total running time of the
    time       program used by this function.
     
    cumulative a running sum of the number of seconds accounted
     seconds   for by this function and those listed above it.
     
     self      the number of seconds accounted for by this
    seconds    function alone.  This is the major sort for this
               listing.
     
    calls      the number of times this function was invoked, if
               this function is profiled, else blank.
     
     self      the average number of milliseconds spent in this
    ms/call    function per call, if this function is profiled,
    	   else blank.
     
     total     the average number of milliseconds spent in this
    ms/call    function and its descendents per call, if this 
    	   function is profiled, else blank.
     
    name       the name of the function.  This is the minor sort
               for this listing. The index shows the location of
    	   the function in the gprof listing. If the index is
    	   in parenthesis it shows where it would appear in
    	   the gprof listing if it were to be printed.
    Le résultat est suffisamment verbeux. Ensuite pour avoir un détail de ce qui se passe dans les fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    > gcov -df main.c
    Processing file 1 out of 1
    Function 'main'
    Lines executed:100.00% of 4
     
    Function 'distance'
    Lines executed:100.00% of 7
     
    Function 'syracuse'
    Lines executed:80.00% of 10
     
    File 'main.c'
    Lines executed:90.48% of 21
    Creating 'main.c.gcov'
    Tu as un rapport sommaire de la couverture : il n'y a que dans la fonction syracuse qu'il y a du code non exécuté, regardons ça en détails en consultant le fichier main.c.gcov :
    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
          189:    3:int syracuse(int n)
            -:    4:{
            -:    5:  int resultat;
            -:    6:  int i;
            -:    7:
          189:    8:  switch (n%2) {
            -:    9:  case 0:
          139:   10:    resultat = n/2;
          139:   11:    break;
            -:   12:  case 1:
           50:   13:    resultat = 3*n + 1;
           50:   14:    break;
            -:   15:  default:
        #####:   16:    printf("Non impossible d'arriver ici !!!!\n");
        #####:   17:    break;
            -:   18:  }
            -:   19:
          189:   20:  for(i=0;i<10000000;++i);
            -:   21:
          189:   22:  return resultat;
            -:   23:}
    Chaque ligne est préfixé par le nombre d'exécution, si elle est préfixée par - c'est que cette ligne ne produit pas de code et si elle est préfixée par ###### c'est que bien que cette ligne corresponde à du code, elle n'a jamais été exécutée.

    Avec l'option -b passée à gcov tu as en plus les stats sur les conditionnelles :
    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
          189:    8:  switch (n%2) {
    branch  0 taken 74%
    branch  1 taken 26%
    branch  2 taken 0%
            -:    9:  case 0:
          139:   10:    resultat = n/2;
          139:   11:    break;
            -:   12:  case 1:
           50:   13:    resultat = 3*n + 1;
           50:   14:    break;
            -:   15:  default:
        #####:   16:    printf("Non impossible d'arriver ici !!!!\n");
    call    0 never executed
        #####:   17:    break;
            -:   18:  }
    Le case 0 est pris dans 74% des cas, le case 1 26% et le default jamais.

    test.zip

  14. #14
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Merci pour l'explication détaillée. C'est beaucoup plus clair maintenant
    Je devrais pouvoir m'en sortir avec ces infos là.

    Même si ca n'a pas vraiment de rapport avec le sujet actuel, j'ai un dernier soucis au niveau de mon programme de vérification de fuites de mémoire. Pour un programme C, pas de soucis, ca marche très bien mais pour un programme C++, cela ne fonctionne plus.
    J'ai redéfini les opérateurs new, new[], delete et delete[] et j'ai créé mes macros :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define new new(__FILE__, __LINE__)
    #define delete __CheckMemory_cplusplus_prepareDelete(__FILE__, __LINE__), delete
    Problème, vu qu'on mon programme injecte le header "CheckMemory.h" en haut de chaque fichier source et que les macros sont dedans, pour un programme en C++, il y a des problèmes car la redéfinition des opérateurs new/delete interfère avec les libs standard à savoir <iostream> ou <vector> par exemple. Du coup, il faut placer nos macros en dessous de tous les #includes mais cette opération est difficilement réalisable automatiquement

    En gros, dans cet ordre, le code compile et les surcharges fonctionnent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "checkMemory.h"
     
    #include <iostream>
    #include "head.h"
    #include <ctime>
    #include <cstdlib>
    #include <cstdio>
     
    #define new new(__FILE__, __LINE__)
    #define delete __CheckMemory_cplusplus_prepareDelete(__FILE__, __LINE__), delete
    Mais si je mets les macros dans checkMemory.h ou alors juste en dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include "checkMemory.h"
    #define new new(__FILE__, __LINE__)
    #define delete __CheckMemory_cplusplus_prepareDelete(__FILE__, __LINE__), delete
     
    #include <iostream>
    #include "head.h"
    #include <ctime>
    #include <cstdlib>
    #include <cstdio>
    Cela ne fonctionne plus à cause des conflits dans <iostream>...

    Y'a t-il une autre solution pour surcharger les opérateurs new/delete ? (un peu comme à la méthode C)

    PS : Pour rappel, mon programme automatique ouvre les fichiers sources et ajoute au debut la ligne suivante : #include "CheckMemory.h"
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  15. #15
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Autant la manipulation avec malloc et free me semblait à la limite du viable mais encore faisable, autant définir des macros new et delete me semble quand même casse-gueule.
    Finalement en googlant un peu (valgrind win32) on trouve via une question sur SO un outil qui ressemble : DrMemory (il me semble l'avoir lu en plus dans une discussion précédente en plus ...). Ça me semble plus stable comme solution.

    EDIT : Metalman l'avait proposé dans une autre discussion ... bien vu Metalman.

  16. #16
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Oui on m'avait déjà proposé cette solution, cet outil est récent, il y a quelques années, il n'existait pas d'équivalent à valgrind pour windows. Je le garde précieusement sous le coude.

    J'aurais quand même préféré trouver une solution pour ma propre application car elle est customizée pour ce que je veux en faire au niveau pédagogique (elle n'est pas destinée à des gurus de la programmation à l'affut de la moindre fuite ^^ )

    Redéfinir les opérateurs en C++ se fait très bien c'est juste que c'est mon histoire d'injection de code dans les sources qui est un peu bizarre

    Il n'y a vraiment pas une solution "casse gueule" pour mon problème ?
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  17. #17
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Heureux d'avoir indirectement aidé !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  18. #18
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Citation Envoyé par Metalman Voir le message
    Heureux d'avoir indirectement aidé !


    Bon, je crois que pour le C++ ca ne sera pas faisable avec les surcharges
    De toute manière c'est pas très grave, j'en ai besoin que pour les programmes en C dans un premier temps, sinon tant pis faudra voir du côté de Dr Memory

    Merci à vous pour votre aide !
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/04/2015, 10h45
  2. Réponses: 4
    Dernier message: 21/04/2011, 08h31
  3. Réponses: 4
    Dernier message: 30/10/2007, 21h03
  4. [xslt][xpath]Obtenir le nom du jour a partir d'une date
    Par Thomus38 dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 10/09/2007, 11h49
  5. Réponses: 6
    Dernier message: 06/04/2007, 21h20

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