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++Builder Discussion :

[CodeGuard]Thread et DLL : problème de #define [Langage/Algorithme]


Sujet :

C++Builder

  1. #1
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 665
    Points : 25 459
    Points
    25 459
    Par défaut [CodeGuard]Thread et DLL : problème de #define
    Sur C++Builder 2007, je m'occupe d'un projet dont certains modules sont des EXE utilisé en DCOM

    En Debug, je lance l'Exe directement, donc pas de DCOM
    Celui-ci contient un Thread Principal (VCL) et un Thread Secondaire
    Dans le Thread Secondaire, à un moment donné je lance un 3eme Thread
    Dans ce 3eme Thread, j'utilise des Objets et des Interfaces (classes abstraites pures) qui sont implémentées par plusieurs DLL

    Les DLL via LoadLibrary sont chargées dynamiquement en fonction de la DB (une sorte de système de Proxy\Drivers pour pilotage de périphérique avec une forte volonté de généricité)

    Après le LoadLibray, je fais appel à procédure dont l'adresse est récupérée par GetProcAddress, une bonne séquence de code s’exécute sans problème !
    J'accède même à certaines des #define avec TRegistry

    A un moment donné j'utilise un objet commun à tous les projets, une sorte de boite à outil !
    Des instances de cet objet ont été créées sans aucun soucis dans l'Exe ainsi que d'autres d'autres DLL déjà chargées !
    Cet objet durant sa construction utilise des #define

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifdef VERSION_BIBULE
      #define KEY_ROOT_REG "SoftWare\\Bidule"
      #define NAME_APPLICATION "Bidule"
      #define VERSION_KEY "VersionBidule"
    #else
      #define KEY_ROOT_REG "SoftWare\\Machin"
      #define NAME_APPLICATION  "Machin"
      #define VERSION_KEY "Version"
    #endif
    Cet Exe peut être compilé pour deux logiciels séparés utilisant des répertoires et BDR différentes !
    Je suis en "BIDULE" en ce moment !

    le moindre accès à une chaine définie par ces macros provoque un avertissement CodeGuard :
    Sur-dépassement Pointeur arithmétique en cours de traitement : Programme.exe(15476) - ..\..\Machin\commun\ObjetBoiteOutil.cpp#2347
    0x043A2D45+3118, qui est sur offset 424+3118 dans le bloc d'adresse 0x043A2B9D(=Truc.dll:0x02:000B9D) dont la longueur est seulement de 512 octets.
    Je suppose que cela correspond à Sur-dépassement Accès mais sur une constante chaine ???
    Comme si l'espace mémoire de la DLL n'était pas top top !

    les fonctions utilisant ces #define sont RegOpenKeyEx, RegQueryValueEx, strcmpi, j'ai aussi testé strlen ou OutputDebugString !
    Le code fonctionne parfaitement mais CodeGuard panique un peu !
    Tout en version ANSI

    le plus Etrange, j'ai déplacé la création (je pratique le lazyloading) des mes objets et interfaces dans le Second Thread
    Ce qui implicitement charge les DLL avec LoadLibray et appel des procédures récupérées pas GetProcAddress
    Mystère plus de problème avec CodeGuard !

    J'ai aussi tenté de mettre le code du Execute comme une simple fonction non threadé directement dans le Thread Principal, disons que son comportement semble dépendre de la pression atmosphérique, un coup, CodeGuard ne dit rien, le coup suivant il m'affiche ces warnings !
    Cela dépend si je fais F7 (descente du pas à pas) ou F8 (pas à pas simple)

    De plus, ces même objets et interfaces sont utilisés dans deux autres exécutables, le chargement des DLL et l'appel de procédure ne posent aucun problème !

    Questions (oui enfin) :
    - Est-ce mal de faire un LoadLibrary depuis un Thread (lui même lancé depuis un Thread)
    - Est-ce juste CodeGuard qui panique avec les Threads ?

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 665
    Points : 25 459
    Points
    25 459
    Par défaut
    J'ai poussé mes recherches !

    J'ai constaté que j'avais des problèmes à partir du moment où je déchargeais une DLL contenant des informations de débogages de CodeGuard !

    Je crois que c'est CodeGuard qui délire, il croit qu'il utilise la DLL qui a été déchargée alors qu'il est en train de débuggueur une autre DLL qui a pris un espace mémoire proche (ou carrément le même !)

    Je pense que ce sujet est clos, un bug du déboggueur

  3. #3
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut
    Il me semble que ton problème avec des messages aléatoires de CodeGuard dépendant le la partie de ton application ou tu instancies des objets et interfaces contenus (si j'ai bien suivi) dans différentes dll est un probléme de gestion de la mémoire.
    Tes DLL a un certain moment consomment trop et ne release pas correctement la mémoire attribuée.

    regarde cette excellent article de MS sur le sujet "Using Thread Local Storage in a Dynamic-Link Library"
    http://http://msdn.microsoft.com/en-...(v=VS.85).aspx

    cordialement

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 665
    Points : 25 459
    Points
    25 459
    Par défaut
    En retirant le FreeLibrary lorsqu'il détecte le chargement d'une DLL qui ne répond pas au critère de fonctionnement (présence de certains fonctions exportées, retour d'une interface générale et accrochage de Event), je n'ai plus le problème

    Avec FreeLibrary, l'adresse de base de la DLL déchargée est très rapidement réutilisé par une autre DLL !
    Sans FreeLibrary, l'adresse de base reste séparée !

    En fait, ce n'était pas aléatoire !

    Dans le second thread, la boucle qui charge les objets chargeait dans un ordre étrange (une requête SQL avec un UNION) par exemple la 8, la 1 puis le 2 et la 4 ... cet ordre étrange étant l'ordre alphabétique sur le nom du périphérique, je ne comprends pas bien pourquoi ce choix par le précédent développeur alors que la requête sert à un Polling dans un Service Windows sans aucune IHM, peu importe l'ordre dans un tel programme !

    Dans le troisième thread, les ID ont été stockés dans un std:set c'était pour éviter les doublons mais ils sont automatiquement triés ce conteneur (ça n'était pas volontaire, c'est surement lié à l'optimisation)
    Et là, je récupère 1, 2, 3, 4, ... hors la 1 utilise une DLL incorrecte, la 4 et la 8 utilise la bonne DLL (celle où j'avais des messages étranges)
    Si je charge la 8 en premier, pas de soucis, si je charge la 1 en premier, il y a le bug !
    J'ai fait l'essai avec une troisième DLL en veillant à ce que l'ordre fasse en sorte que cela charge la bonne DLL puis la mauvaise puis la 3eme, et pouf dans la 3eme dans un code différent se prend des avertissements de CodeGuard sans aucun sens !

    Ce n'est pas un problème de Thread, j'ai réussi à provoquer l'erreur depuis le MainThread, une fois que j'avais identifié la séquence il devenait facile de reproduire le phénomène
    Evidemment, je testais le chargement de la 4, qui fonctionnait très bien tout seul d'où mon impression d'aléatoire !
    C'est une fois que j'ai testais 1 puis 4 que j'ai compris ce qui se passait !

    Je ne pense pas que cela soit un problème de Gestion Mémoire, tout simplement parce que la DLL déchargée, n'alloue rien !
    J'ai même fait une DLL exprès qui ne fait rien du tout, juste une fonction avec un corps vide et le minimum d'include que possible ! Le bug était toujours là !

    J'ai testé avec plusieurs DLL qui ne respecte pas le contrat et donc sont déchargées, toute me provoque un délire de CodeGuard !

    J'avais lu une ancienne version de l'article mentionné, je l'ai exploré en Delphi pour gérer un Multiton créant un objet par thread géré par un singleton commun à tous les threads !
    Je n'avais pas bien compris à l'époque ce TlsAlloc, ce n'est pas beaucoup mieux aujourd'hui

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

Discussions similaires

  1. [C#] DLL, problème de constructeur
    Par gmonta dans le forum C#
    Réponses: 4
    Dernier message: 30/11/2005, 09h43
  2. [cygwin1.dll] Probléme avec cygwin1.dll
    Par Furius dans le forum Windows
    Réponses: 7
    Dernier message: 29/11/2005, 21h18
  3. [DLL] Problèmes d'accès et de mise a jour du fichier
    Par Clorish dans le forum Langage
    Réponses: 14
    Dernier message: 27/06/2005, 14h28
  4. [DLL] problème pour appeler une fonction d'une DLL
    Par bigboomshakala dans le forum MFC
    Réponses: 34
    Dernier message: 19/07/2004, 11h30
  5. Réponses: 4
    Dernier message: 01/07/2004, 11h53

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