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 :

Partage d'une DLL entre deux process : Prolbèmes - Astuces ?


Sujet :

Windows

  1. #1
    Membre éclairé
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Points : 785
    Points
    785
    Par défaut Partage d'une DLL entre deux process : Prolbèmes - Astuces ?
    Bonjour,

    Ayant une DLL employée par deux applications, est-il possible que le partage de cette DLL pose problèmes.
    Explications:

    La première application charge une Dll via LoadLibrary, une seconde application charge aussi la Dll.
    Tout semble fonctionner correctement, sauf que lorsque j'appel certaines fonctions provenant de la dite Dll depuis la seconde application, j'ai des exceptions de violation d'accès. Pour moi, il s'agit d'un problème de Mapping.

    Y a-t-il une astuce pour pouvoir charger une Dll autant de fois ? Le code est-il réentrant ?

    Merci
    Nul ne peut mieux connaitre la connaissance qu'elle-même.

  2. #2
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Bonjour,
    Ce problème est typique de ressources interne à la DLL non process-safe.

    Par exemple si la DLL se base sur des variables alloués dynamiquement, le premier chargement ne pose pas problème, mais lors du second chargment, suivant comment est codée la DLL, l'allocation dynamique n'est pas faîte.

    Tu as les sources de la DLL? Si oui, tu peux vérifier s'il y a des mapping pour travailler avec de zones partagées entre process ou non.

    Ces mapping sont allouées via CreatFileMapping.

    Il peut aussi y avoir un problème de mutex voir de section critique, notamment si la création de ces entités ne se fait pas au bon endroit.

    Et oui, les variables globales ne sont pas partagées entre process.

  3. #3
    Membre éclairé
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Points : 785
    Points
    785
    Par défaut
    Quand on charge une Dll dans un process, l'espace mémoire utilisé par la Dll est propre au process dans laquelle elle est chargée ?

    Dans notre cas, il n'y a pas de zones mémoires partagées entre les différentes instances de la DLL.
    Nul ne peut mieux connaitre la connaissance qu'elle-même.

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Par défaut une dll ne partage rien entre les différent process qui l'utilisent. Autrement dit, à moins que tu ais explicitement créé une section partagée, c'est comme si tu avais copié ta dll dans le répertoire de chaque process, et que chacun chargeait sa dll.
    Si ça plante, c'est simplement un bug dans la dll ou dans la manière dont elle est utilisée. Si tu cherches à partager des données entre les process de manière directe dans ta dll, alors c'est normal que ça plante.
    Encore faut il identifier précisément l'endroit de l'erreur, à l'aide d'un débogueur par exemple.

  5. #5
    Membre éclairé
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Points : 785
    Points
    785
    Par défaut
    En fait, le problème est que nous avons créé une DLL via Borland C++ Builder, et que l'on obtient des exceptions lors de l'utilisation d'une seconde instance de la DLL. Il semblerait que le problème provient du BDE fourni par Borland.

    Est-ce que tu penses que cela peut être vraiment cela, vu que c'est le seul point où l'on fait des accès à une mémoire partagée, c-à-d celle du BDE.

    Merci
    Nul ne peut mieux connaitre la connaissance qu'elle-même.

  6. #6
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Pourquoi ne fais-tu pas de pas à pas dans la DLL pour savoir où ça plante?

    E pas à pas toujours, tu peux stopper avant la fonction qui plante et regarder le call stack.

    Autre point, s'assurer qu'il n'y a as de déchargement intempsetif de la DLL.

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par swirtel
    Quand on charge une Dll dans un process, l'espace mémoire utilisé par la Dll est propre au process dans laquelle elle est chargée ?
    Oui, par rapport au processus courant.
    Brièvement :
    - La seule chose commune entre deux "instances" de la DLL (pour deux processus différents), c'est que le CODE de la DLL n'est réellement présent qu'UNE SEULE FOIS sur l'OS. Cependant, l'adresse d'une fonction donnée peut (et souvent, EST) différente pour chaque processus : c'est lié au mapping mémoire virtuel de l'OS.
    - Toutes les variables internes à la librairies, ainsi que les allocations mémoire faites, les variables statiques, etc... sont propres à CHAQUE processus utilisateur.

    Je ne crois pas que l'accès BDE soit thread-safe : normalement, il te faut implémenter un mutex nommé pour ça. Il faudrait que tu consultes la documentation Borland sur le sujet.

    Sinon, tu as la possibilité de "sniffer" l'initialisation de ta DLL en greffant des message de debug dans ton DllMain, sur les évènement "PROCESS_ATTACH" et "THREAD_ATTACH" notamment. Pense à afficher le PID et le TID des appelants à chaque fois.
    Pour tester le déchargement intempestif, il faut et il suffit de vérifier les évènements "PROCESS_DETACH" et "THREAD_DETACH" du DllMain.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Est-ce que tu penses que cela peut être vraiment cela, vu que c'est le seul point où l'on fait des accès à une mémoire partagée, c-à-d celle du BDE.
    elle est de quel type cette mémoire partagée ?
    - Toutes les variables internes à la librairies, ainsi que les allocations mémoire faites, les variables statiques, etc... sont propres à CHAQUE processus utilisateur.
    sauf dans le cas d'une section partagée

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    - Toutes les variables internes à la librairies, ainsi que les allocations mémoire faites, les variables statiques, etc... sont propres à CHAQUE processus utilisateur.
    sauf dans le cas d'une section partagée
    [Mode "J'ai raison"]
    Le handle sur la mémoire partagée (seule variable appartenant réellement à la DLL) est bel et bien privé (et différent !!) pour chaque processus d'attachement...
    C'est le contenu de cette zone partagée, qui n'appartient pas à la DLL, qui est commun...
    Allons, Aurélien, ne me dit pas que tu confonds "pointeur" et "objet pointé" ? ;-)
    [/Mode "J'ai raison"]

    Bon, c'est pas tout de se lancer des vannes, soyons sérieux.
    Ce concept de duplication des données de la DLL pour chaque processus est réellement incontournable : une zone partagée n'appartient pas vraiment à un processus en particulier... C'est le dernier handle fermé qui détermine sa destruction, mais il n'est nullement nécessaire que ce soit le même processus que celui ayant créé la zone avec la première création de handle !
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Je parlais de ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #pragma data_seg(".SHARED")
    
    int variable_partagee = 0;
    
    #pragma data_seg()
    #pragma comment(linker, "/section:.SHARED,RWS")
    Si les process A et B utilisent une dll qui définit variable_partagee ainsi, les 2 partageront la même variable, ainsi que toutes celles déclarées dans ce bloc commun.
    Ca marche aussi pour les exe (pour tous les fichiers PE en fait).
    http://www.codeguru.com/Cpp/misc/misc/ipctechniques/article.php/c305/

  11. #11
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Je parlais de ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #pragma data_seg(".SHARED")
    
    int variable_partagee = 0;
    
    #pragma data_seg()
    #pragma comment(linker, "/section:.SHARED,RWS")
    Nan nan nan nan... Là, tu es en train de me parler d'extensions implémentées par Visual C++, qui en plus sont basées sur des forçages du mapping mémoire (=> super dangereux, en plus). Et ce n'est pas un concept de DLL, mais d'implémentation "cachée" spécifique VC++ : les #pragma sont rarement portables, même au sein d'un même OS !! Ca ne marche pas sous Delphi, VB ni BCB, par exemple...

    De plus, regarde les fonctions exportées de ta DLL : tu risques d'avoir une surprise désagréable avec ce type de code, genre fonctions "inconnues" rajoutées, greffées sur DllMain(PROCESS_ATTACH). C'est ce que fait VC++ lorsque tu fais une DLL exportant des variables et/ou des classes (et bonjour pour utiliser la DLL avec un autre compilateur sans son .LIB associé, au passage...).

    Or, puisqu'il utilise BDE, c'est qu'il est sous un compilateur Borland : Delphi ou BCB... ;-) La seule solution portable sur tous les langages est l'API Win32, en créant un partage mémoire.

    J'ai bien raison...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  12. #12
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    C'est pas une extension spécifique VC++ du tout, c'est standard et documenté dans le format PE, c'est standard Windows en somme (voir le champ Characteristics de IMAGE_SECTION_HEADER). C'est Windows qui en interne s'occupe du mapping spécifique de la section commune. A priori n'importe quel compilo pourrait offrir cette possibilité, VC++ permet de la faire via pragma / ligne de commande (/SECTION).
    GCC permet de le faire avec l'attribut __attribute__((section ("shared"), shared)).
    Borland je sais pas.

  13. #13
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    C'est pas une extension spécifique VC++ du tout, c'est standard et documenté dans le format PE, c'est standard Windows en somme (voir le champ Characteristics de IMAGE_SECTION_HEADER). C'est Windows qui en interne s'occupe du mapping spécifique de la section commune. A priori n'importe quel compilo pourrait offrir cette possibilité, VC++ permet de la faire via pragma / ligne de commande (/SECTION).
    GCC permet de le faire avec l'attribut __attribute__((section ("shared"), shared)).
    Borland je sais pas.
    C'est quand même un forçage du mapping mémoire, ce qui n'est pas foncièrement une bonne idée sur un OS qui, normalement, isole chaque processus des autres. Ca rejoint le principe des segments nommés des compilateurs 16 bits, lorsque l'on mappait des variables sur des segments particuliers (vraiment au hasard, la mémoire vidéo, ou la zone AT en bas de RAM).
    J'avoue que je ne savais pas que c'était une caractéristique PE, par contre : le coup des "fonctions planquées" est surtout visible avec les variables et les classes exportées des DLL VC++ ("Regular DLL that exports some symbols" dans les templates).

    Mais dans tous les cas, je trouve ce genre de technique de "partage" particulièrement dangereuse : la manière de partager n'est pas portable de compilateur en compilateur (ça, c'est quand même gênant, tu ne crois pas ?), et j'émets quelques réserves sur la possibilité d'utiliser ce genre de choses avec d'autres langages (ex : Delphi). Or, le but d'une DLL est avant tout d'étendre les possibilités du langage ou du système, et faire des DLL spécifiques à un langage ou un compilateur est une aberration complète... Une bonne DLL est utilisable avec tous les langages/compilateurs, quel que soit le langage utilisé pour la développer.
    Ton truc, c'est un peu trop "bidouille" : ça peut aller lorsque c'est Microsoft qui l'utilise pour les DLL de l'OS lui-même, mais pas pour un programme tiers. Du moins, pas pour quelque chose de professionnel.

    Tu fais quoi le jour où ton compilateur n'est plus maintenu ? Ou que l'implémentation de cette "fonctionnalité" change ? Ou si les caractéristiques du format PE changent sur la prochaine version de Windows ? As-tu la garantie que ça fonctionne également sur d'autres plate-formes Win32 "particulières", comme WinCE ou XPE ? Ca me rappelle un peu trop d'anciennes techniques du DOS, qui ont fait qu'une grande partie de la logithèque DOS/Win16 n'est plus du tout exécutable sur XP désormais...

    Par contre, un partage fait "normalement", par CreateFileMapping, est portable quel que soit ton compilateur, c'est évolutif quelle que soit l'implémentation réelle au sein de l'OS, et la même technique est utilisable avec tous les langages permettant les appels de DLL Win32. La supériorité de cette méthode est sans appel.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  14. #14
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    J'ai jamais prétendu que c'était mieux ou moins bien. J'ai juste dit que ça existait. Libre à toi d'estimer si c'est une bonne pratique ou non.
    C'est rarement utilisé. Le cas le plus courant c'est pour réaliser des hook.

  15. #15
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    J'ai jamais prétendu que c'était mieux ou moins bien. J'ai juste dit que ça existait. Libre à toi d'estimer si c'est une bonne pratique ou non.
    Ben en l'occurrence, je pense que tu auras remarqué ce que j'en pense...

    Citation Envoyé par Aurelien.Regat-Barrel
    C'est rarement utilisé. Le cas le plus courant c'est pour réaliser des hook.
    Merci de le préciser. Tu admettras qu'un hook n'est pas spécialement ce que l'on peut appeler une opération "normale", surtout lorsqu'il est nécessaire de se greffer sur un élément de l'OS de cette manière pour le réaliser... ;-)
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

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

Discussions similaires

  1. Partage d'une table entre deux sites distants
    Par ishikawa dans le forum Access
    Réponses: 1
    Dernier message: 01/04/2013, 20h48
  2. Partage d'une Textbox entre deux class
    Par lexius dans le forum Windows Forms
    Réponses: 1
    Dernier message: 30/04/2008, 16h02
  3. [TOMCAT] Partager une dll entre 2 webapp
    Par lucho31 dans le forum Tomcat et TomEE
    Réponses: 7
    Dernier message: 18/12/2005, 20h48
  4. partager ressource entre deux process
    Par buzzz dans le forum Windows
    Réponses: 6
    Dernier message: 16/02/2005, 10h36
  5. TList partagée entre deux process.
    Par swirtel dans le forum C++Builder
    Réponses: 2
    Dernier message: 10/01/2005, 11h48

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