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

Threads & Processus C++ Discussion :

la zone memoire d'un processus : debut fin


Sujet :

Threads & Processus C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 84
    Points : 42
    Points
    42
    Par défaut la zone memoire d'un processus : debut fin
    bonjour
    je sais comment trouver "l'adresse memoire" de "debut" de la "zone memoire" d'un processus.

    comment je pourrai trouvez l'adresse memoire de sa fin ?

    merci pour votre aide

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par ilimo
    je sais comment trouver "l'adresse memoire" de "debut" de la "zone memoire" d'un processus.
    comment ?

    C'est spécifique a chaque OS. Y'a pas vraiment de fin dans la mesure ou il y a des "trous", et que des dlls systemes sont mappés dans l'espace mémoire de ton process, que y'a des parties en lecture seule, etc... Et que surtout ca évolue constament.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 84
    Points : 42
    Points
    42
    Par défaut
    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
     
    void Process_Adress_Debut()
    {
    hProcess_Open = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id_);
    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proc_id_); 
    if (hModuleSnap == INVALID_HANDLE_VALUE)
    {
    printf("snapshot impossible");
    }
     
    me32.dwSize = sizeof(MODULEENTRY32);
     
    Module32First( hModuleSnap, &me32 );
    do 
    { 
    Module32Next( hModuleSnap, &me32 );
    if(StrCmp(me32.szModule, "MyProcess.dll")== 0)
    { 
    printf( "\n dll name : %s", me32.szModule ); 
    printf( "\n base address = 0x%08X", (DWORD) me32.modBaseAddr );
    MyProcess_BaseAdr = (DWORD) me32.modBaseAddr;
    }
    } 
    while( StrCmp(me32.szModule, "MyProcess.dll")!= 0); 
     
    CloseHandle(hModuleSnap);
    }
    _____________________________________________________________
    que surtout ca évolue constament
    Chaque donnée stockée en mémoire principale (variable, fonction) a un emplacement unique, ceci lors de la meme execution( lors d'une autre, ça change)

    L'allocation dynamique de mémoire permet la réservation d'un espace mémoire

    Effectuer une allocation dynamique de mémoire, c'est demander au système de vous réserver un bloc de mémoire, que vous pourrez utiliser à votre convenance
    _____________________________________________________________

    ainsi, à chaque nouvelle execution de Myprocess.dll, je calcule l'adresse de base.
    de cette manière toutes les données manipulées par Myprocess.dll
    sont stockées dans des adresses mémomoires à partir de l'adresse memoire de base.
    on peut ignorer tout ce qui est avant cette adresse base.

    mais ce processus jusqu'à quelle adresse prend de l'espace ??

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Si tu effectues plusieurs alloc, tu as donc plusieurs blocs mémoire réservés par le systeme... et des "trous" = fragmentation. Et un bloc alloué se libere... donc ca évolue a chaque allocation / libération, c.a.d constament. Fait une petite recherche sur le working set size sous Windows, et tu vas mieux comprendre. Exemple simple:
    Lance une appli, regarde sa consommation mémoire dans le gestionnaire des taches (Le "Mem Usage", = working set size). Minimise l'application et observe comment ca évolue... Et l'appli n'y est pour rien, c'est Windows qui gere l'espace mémoire du process, en fonction des dlls mappées etc...

    Sinon, ton code et ta question sont spécifiques Windows. Tout ton code de Process_Adress_Debut() ne sert a rien vu que Windows te donnes cette "adresse de début" en 1er parametre de DllMain.
    Et un simple GetModuleHandle("MyProcess.dll") ferait la meme chose.

    ainsi, à chaque nouvelle execution de Myprocess.dll, je calcule l'adresse de base.
    de cette manière toutes les données manipulées par Myprocess.dll
    sont stockées dans des adresses mémomoires à partir de l'adresse memoire de base.
    on peut ignorer tout ce qui est avant cette adresse base.
    Tu mélanges dll et process. L'adresse recue / renvoyée par ta fonction n'est pas l'adresse "de début" du process, mais l'adresse a laquelle est mappée ta dll.

    Il y a de tres fortes chances que ta dll alloue de la mémoire avant cette adresse. Fais juste un test, pour voir, sur l'adresse renvoyée par new. Car l'adresse du tas est tres certainement située avant celle de ta dll. Pire, ta dll peut utiliser la meme CRT que l'exe, ce qui a pour consequence que ta dll utilise la meme memoire que l'exe.
    mais ce processus jusqu'à quelle adresse prend de l'espace ??
    Il ne prend pas un gros bloc contiguë, mais plein de blocs plus ou moins gros, avec des "trous" entre-eux.

    La grande question est : qu'essayes-tu de faire ? Pourquoi as-tu besoin de cette info ?

  5. #5
    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 519
    Points
    41 519
    Par défaut
    Euh, au sujet des GetModuleHandle()...
    Je ne voudrais pas paraître défaitiste, mais d'après la structure MODULEENTRY32, handle de module et adresse de base sont deux choses différentes...
    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.

  6. #6
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Et poutant... Le HMODULE est un reliquat de Win16, ca n'a plus de sens de nos jours. Code modifié:
    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
    36
    37
    38
    39
    40
     
    #include <windows.h>
    #include <Tlhelp32.h>
    #include <stdio.h>
     
    void Process_Adress_Debut()
    {
      DWORD proc_id_ = GetCurrentProcessId();
      HANDLE hProcess_Open = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id_);
      HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proc_id_); 
      if (hModuleSnap == INVALID_HANDLE_VALUE)
      {
        printf("snapshot impossible");
      }
     
      MODULEENTRY32 me32 = {0};
      me32.dwSize = sizeof(MODULEENTRY32);
     
      Module32First( hModuleSnap, &me32 );
      do 
      { 
        Module32Next( hModuleSnap, &me32 );
        if(strcmp(me32.szModule, "kernel32.dll")== 0)
        { 
          printf( "\n dll name : %s", me32.szModule ); 
          printf( "\n base address = 0x%08X", (DWORD) me32.modBaseAddr );
          printf( "\n hModule = 0x%08X", (DWORD) me32.hModule );
        }
      } 
      while( strcmp(me32.szModule, "kernel32.dll")!= 0); 
     
      CloseHandle(hModuleSnap);
    }
     
    int main()
    {
        Process_Adress_Debut();
        printf( "\n GetModuleHandle(kernel32) = 0x%08X",
          GetModuleHandle( "kernel32.dll" ) );
    }
    résultat:

    dll name : kernel32.dll
    base address = 0x7C800000
    hModule = 0x7C800000
    GetModuleHandle(kernel32) = 0x7C800000

  7. #7
    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 519
    Points
    41 519
    Par défaut
    OK.
    Pour moi, c'est plutôt le HINSTANCE qui est un reliquat, et je pensais le HMODULE légitime (et donc, potentiellement différent de son adresse de base).

    D'ailleurs, je ne sais pas si même de nos jours, c'est garanti officiellement par l'API. Surtout sachant qu'il y a quand même deux champs dans une structure 32 bits...
    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.

  8. #8
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Ca doit etre pour que du vieux code compile. De meme que wParam n'est plus un WORD depuis longtemps...
    Dans le cas de kernel32, l'OS te garantit que son adresse de base est toujours 0x7C800000.

  9. #9
    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 519
    Points
    41 519
    Par défaut
    Pour compiler du vieux code, il n'y aurait pas 32 dans le nom...
    Surtout que les processus n'existaient pas en 16-bits, ni ToolHelp32, à mon avis.

    Peut-être que ça pouvait être différent sous les Windows non-NT ?
    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.

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Win 3.x était multiprocess coopératif. Le 16 bits n'empêche pas le multiprocess, tant qu'on est en mode protégé. La première version d'OS/2 était en 16 bits.
    Windows NT a été 32 bits depuis le début (a la base, il devait être un successeur à OS/2).

    Concernant le cas particulier de MODULEENTRY32, je dois avouer que j'en sais rien. C'est juste que bien souvent, dans ce genre de cas, la réponse se trouve du coté de la compatibilité ascendante.

  11. #11
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    il y a des trous même dans la zone mémoire réservée à une variable?

    Parceque sinon on pourrait faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool *debut = (bool*)(void*)(&variable);
    bool *fin = debut + sizeof(variable);
    fin pointerait sur le bit juste après le dernier bit de la variable.

    on pourrait faire --fin pour le faire pointer sur le dernier bit.

  12. #12
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par coyotte507
    il y a des trous même dans la zone mémoire réservée à une variable?
    Non, bien sur que non. Il faut avoir une vision plus générale que le C++, au niveau de l'OS. En mémoire ton programme possède une zone de code, de mémoire, de mémoire readonly, etc... C'est le cas pour ton exe, et pour les dlls. Et ton process, c'est 1 exe + x dlls, donc autant de zones en mémoire, avec des trous entre-elles.
    Une image pour un peu mieux comprendre:
    http://www.flounder.com/hooks.htm

    Du point de vue du C++, tu compiles 1 exe ou 1 dll, donc avec sa propre zone de mémoire a elle = le tas, qui est bien un bloc entier contigüe, sans trou (encore que, le compilo peut en fait gérer plusieurs tas, et alors...).

  13. #13
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Attendez... je vais peut-etre sortir une énormité....

    Mais il me semblait que de toute maniere, on avait qu'un 'mapping' de la mémoire...

    Je veux dire, tout process se trouve attribué 2Go (sous 32-bits) d'espace d'addressage... et l'OS se charge de mapper ca sur des vraies addresses dynamiquement.
    Mise à part, bien sur, le petit Go sensé être "partagé" (et qui ne l'est plus depuis longtemps) pour les I/O et autres joyeusetés...

    Un GetProcAddress, HMODULE, ou autre, ne renvoit qu'une addresse dans cet espace virtuel, et ne représente en rien la quantité de mémoire allouée, ou la (les) zones occupées....
    A part taper dans les tables de page mémoire (OS kernel) et demander lequelles sont allouées, et ou ...

    Ou alors, j'ai vraiment rien compris de la problématique initiale
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  14. #14
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    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 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par nicroman
    Mais il me semblait que de toute maniere, on avait qu'un 'mapping' de la mémoire...

    Je veux dire, tout process se trouve attribué 2Go (sous 32-bits) d'espace d'addressage... et l'OS se charge de mapper ca sur des vraies addresses dynamiquement.
    En 32 bits il y a virtuellement 4 Go d'espace d'adressage virtuel. Mais l'OS se réserve 1 Go, et il reste donc 3 Go pour le process : 2Go pour lui + 1Go pour les données partagées. Si ton exe est marqué d'un flag spécial, et que Windows a été démarré avec le switch /3GB, ton process aura droit a 3Go pour son usage personnel.

    Cet espace d'adressage est découpé en petit morceaux = des pages, qui peuvent etre individuellement marqués commes accessibles ou non au process. Sous x86, une page fait 4ko. Une meme page peut etre mappée dans différents espaces virtuels de plusieurs process, a des adresses virtuelles différentes.

    En réalité, sous Windows, la taille du plus petit bloc de mémoire virtuelle adressable n'est pas 4Ko mais 64Ko.VirtualAlloc(), la fonction systeme d'allocation mémoire de base, sur laquelle toutes les autres sont basées, arrondit a 64Ko.
    http://blogs.msdn.com/oldnewthing/ar.../08/55239.aspx
    Toutes les autres fonctions vont utiliser VirtualAlloc pour subdiviser des blocs de 64Ko en plus petits blocs. Donc, du point de vue de l'OS, seule la mémoire allouée via VirtualAlloc compte, et elle consiste en blocs de 64Ko.

    Windows va donc ajuster ton espace d'adressage virtuel a coup de plages de 64Ko. Ces plages ne sont pas forcément entierement mappées en mémoire physique. Elle le sont a coup de pages physiques, donc 4Ko sous x86. Par exemple, quand tu lances un exe, Windows va réserver de l'espace virtuel pour l'ensemble du code exécutable, mais ne va effectivement charger en mémoire que les pages réellement demandée en exécution.

    Si tu alloues 1 octet avec VirtualAlloc, Windows va élargir ton espace d'adressage de 64Ko, et commiter 4Ko en mémoire physique. Le reste de la mémoire virtuelle (64Ko - 4Ko) est perdu. Pour éviter cela, la CRT de ton compilateur C++ va, par exemple, allouer 64Ko, et les remplir petit a petit au fur et a mesure de tes allocations avec new/malloc. Au passage il rajoute des trucs pour vérifier que la mémoire n'est pas corrompue, etc...

    Un GetProcAddress, HMODULE, ou autre, ne renvoit qu'une addresse dans cet espace virtuel, et ne représente en rien la quantité de mémoire allouée, ou la (les) zones occupées....
    Je ne crois pas que ca ait été dit quelque part. Il est tres difficile de calculer la mémoire utilisée par un process, car il y a différents types de mémoire, a comencer par la mémoire partagée. Si tu lances 2 fois le meme exe, son code exécutable va etre partagé en RAM. Comment comptabiliser cette mémoire partagée ?

    En ce qui me concerne, par quantité de mémoire allouée, je parle de la mémoire dynamiquement allouée pour les données, et qui est spécifique a chaque process. Si le process se termine, cette mémoire est effectivement récupérée. C'est la colonne "Taille MV" du gestionnaire de tache, non visible par défaut.

    A part taper dans les tables de page mémoire (OS kernel) et demander lequelles sont allouées, et ou ...
    Il y a les fonctions de la PSAPI:
    http://msdn2.microsoft.com/en-us/library/ms684894.aspx

Discussions similaires

  1. Zone de selection avec date debut et date fin
    Par lanaine07 dans le forum IHM
    Réponses: 1
    Dernier message: 25/05/2011, 08h50
  2. [C# debutant ] zone memoire toujours valide ?
    Par elmcherqui dans le forum C#
    Réponses: 6
    Dernier message: 03/02/2010, 23h11
  3. Representation hexadecimal d'une zone memoire.
    Par etranger dans le forum C++
    Réponses: 6
    Dernier message: 13/03/2007, 14h26
  4. partage memoire entre 2 processus
    Par gudul dans le forum Delphi
    Réponses: 1
    Dernier message: 12/09/2006, 13h43
  5. Rendre une zone memoire accessible a un autre processus
    Par Jack_serious dans le forum POSIX
    Réponses: 12
    Dernier message: 07/12/2005, 21h23

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