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

Windows Discussion :

Bug bizarre.. (nom de fonction interdit ?)


Sujet :

Windows

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 27
    Points : 12
    Points
    12
    Par défaut Bug bizarre.. (nom de fonction interdit ?)
    Bonjour,
    Quand je compile une dll qui exporte une fonction nommée write (ca ne marche qu'avec ce nom), et que dans cette fonction j'utilise la classe ofstream, que j'appelle cette fonction depuis une autre application, le programme bloque et ne se termine pas (ne me demandez pas comment j'en suis arrivé là...) :

    dll.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "dll.h"
    #include <fstream>
    using namespace std;
    // a sample exported function
    void DLL_EXPORT write()
    {
        ofstream test("yoplait.txt");
        test << "slt";
    }
    dll.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #ifdef BUILD_DLL
        #define DLL_EXPORT __declspec(dllexport)
    #else
        #define DLL_EXPORT __declspec(dllimport)
    #endif
    
    extern "C" void DLL_EXPORT write();
    main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include "dll.h"
    
    int main()
    {
        write();    
        return 0;
    }
    J'ai fait des tests intensifs seulement avec le chargement statique de dll (il semble que ça ne fonctionne pas non plus avec le chargement dynamique...). Je ne sais pas si ça un rapport, mais j'utilise code blocks.
    Autre info : quand j'ai débuggé le programme avec OllyDebug, j'ai remarqué (dans le call stack) des appels récursifs à la fonction exportée write
    est-ce que quelqu'un pourrait m'expliquer ce qu'il se passe...

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Peut être (et même surement) que la classe ofstream utilise la fonction write() mais elle voudrait utiliser la vraie, pas la tienne.

    Donc l'éditeur de lien lors de la création de ton binaire se retrouve avec 2 fonction write(), il ne sait pas laquelle choisir, tire au hasard et perd !!

    Peut être aussi qu'il y a un warning généré par le linker lors de la phase de link ou alors un niveau de warning trop faible pour générer cet avertissement.

    D'où l'importance de choisir des noms de fonctions non générique

    Tout ceci n'est que pure spéculation de ma part.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre éclairé Avatar de sloshy
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2005
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 728
    Points : 723
    Points
    723
    Par défaut
    Hello,
    J'ai moi aussi voulu répondre, mais je n'ai pas les compétences, je n'ai pas voulu spéculer sur la chose mais bon

    Je pense un peu comme ram_0000
    La fonction write est une fonction système, lorsque tu crée une dll statique la table IAT doit être crée et prenant compte de ta fonction write et non de celle du système (d'où l'appel récursif dans le débugeur)

    Maintenant, j'aimerai savoir pourquoi ce n'est pas le cas lors d'une dll dynamique, (est-ce qu'une dll dynamique ne fait pas partie de l'IAT?)
    Bref, on vois plus ou moins ce qui se passe, mais on sait pas l'expliquer (je déteste ce genre de situation ^^)

    j'ai continue de me renseigner, je finirai bien par trouvé (ou trouver quelqu'un qui trouve )
    “La seule révolution possible, c'est d'essayer de s'améliorer soi-même, en espérant que les autres fassent la même démarche. Le monde ira mieux alors.”

  4. #4
    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 518
    Points
    41 518
    Par défaut
    Ah en effet, il faut croire que l'implémentation de filebuf() utilise la fonction write() plus-ou-moins-POSIX de la CRT.

    Mais tu aurais du avoir un warning ou même une erreur d'édition de liens...

    Conclusion: Utiliser un autre nom, qui ne soit pas déjà pris.
    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.

  5. #5
    Membre éclairé Avatar de sloshy
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2005
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 728
    Points : 723
    Points
    723
    Par défaut
    Bonjour,
    J'ai repris les codes du 1er post et recompilé sous l'IDE code::block avec gcc comme compilateur.

    Pour les deux sources, j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    warning: command line option "-Wmain" is valid for C/ObjC but not for C++
    Ce qui me semble fort éloigné de ce que l'ont recherche.
    Je compile avec les flags de warning.

    Bref, on sait comment evité le problème mais darkskill le savait aussi avant de venir sur le forum.
    J'avoue, je sèche sur une réponse logique.
    “La seule révolution possible, c'est d'essayer de s'améliorer soi-même, en espérant que les autres fassent la même démarche. Le monde ira mieux alors.”

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par sloshy Voir le message
    Maintenant, j'aimerai savoir pourquoi ce n'est pas le cas lors d'une dll dynamique, (est-ce qu'une dll dynamique ne fait pas partie de l'IAT?)
    Je pense qu'une DLL chargée de façon dynamique (avec load library et getprocaddress()) ne fait pas partie de l'IAT.

    Au fait, cela veut dire quoi IAT, je voie à peu près ce que c'est mais je voudrais en être sûr.

    De toute façon, comment veux-tu que le linker sache quelle(s) librairie(s) tu va charger de manière dynamique.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre éclairé Avatar de sloshy
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2005
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 728
    Points : 723
    Points
    723
    Par défaut
    l'IAT c'est l'Import Address Table
    Elle contient les DLL et les fonctions que l'exécutable va utiliser.
    Elle est construite lors de la compilation du programme et donc effectivement toutes fonctions dynamique n'y figure pas ! (logique )
    “La seule révolution possible, c'est d'essayer de s'améliorer soi-même, en espérant que les autres fassent la même démarche. Le monde ira mieux alors.”

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 27
    Points : 12
    Points
    12
    Par défaut
    Ouais bon, c'est bizarre que je n'ai pas eu d'erreurs d'édition de lien. Je me demande s'il y d'autres noms de fonctions comme ça
    Au fait, quand je disais que ça ne fonctionnait pas pour une dll chargée dynamiquement, je voulais dire que ça buggait aussi (désolé de ne pas avoir été clair la dessus).

  9. #9
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Là, je suis surpris, au fait, c'est quoi une DLL chargée dynamiquement pour toi ?

    Pour moi, c'est LoadLibrary(), GetProcAddress() et appel de la fonction par un pointeur de fonction récupéré par GetProcAddress.

    Est ce qu'il est possible que cette DLL soit chargée dynamiquement par une partie de ton programme et explicitement par une autre partie de ton programme ce qui expliquerait le problème.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 27
    Points : 12
    Points
    12
    Par défaut
    Oui c'est bien de ça que je parle (pour le chargement dynamique de dll). Je viens de refaire un essai, il y a aussi les appels récursifs. Apparemment c'est la dll qui n'est pas compilée corectement.

    [edit]
    Je confirme, c'est bien un problème au niveau de l'édition des liens de la dll.
    J'ai compilé la dll avec la fonction "write" et ensuite avec le nom "ecrit".
    Seulement dans le premier cas je trouve des appels dans le code désassemblé à cette fonction (un nombre d'arguments qui ne correspond pas à son prototype), et ils correspondent au CALL <JMP.&msvcrt._write> du deuxième cas.
    De plus je ne peux pas modifier le fichier .dll manuellement pour que ça fonctionne, car msvcrt._write ne se trouve pas dans la liste des fonctions importée dans le premier cas...

    [/edit]

    edit:
    Ca ne marche pas non plus pour une fonction nommée read qui utilise la classe ifstream

Discussions similaires

  1. [Débutant] appel de fonction qui bug bizarrement
    Par thomMonteillet dans le forum MATLAB
    Réponses: 6
    Dernier message: 07/12/2012, 10h32
  2. Cherche nom de fonction
    Par DeezerD dans le forum Langage
    Réponses: 4
    Dernier message: 15/10/2005, 02h14
  3. Réponses: 2
    Dernier message: 04/10/2005, 16h13
  4. Nom de fonction dynamique
    Par gege2061 dans le forum C
    Réponses: 2
    Dernier message: 21/06/2005, 15h44
  5. Evaluation d'un nom de fonction
    Par uaz dans le forum Général Python
    Réponses: 1
    Dernier message: 04/08/2004, 12h16

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