C plages d’adresses de variables

Comment puis-je imprimer / trouver les plages d’adresses pour tous les types de variables (globales, locales, statiques, etc.). Les plages sont-elles définies par une norme ou puis-je les obtenir avec un outil ou avec une commande bash? Merci pour toute aide 🙂

L’adresse de début d’une variable est fournie par l’ adresse de l’ opérateur & . L’adresse de fin peut être déterminée en ajoutant sa taille à l’adresse de départ moins une – en gardant à l’esprit que l’ajout de 1 à un pointeur avec l’arithmétique de pointeur incrémente l’adresse par la taille de l’object. char* car sizeof(char) == 1 .

Alors:

 start = &var ; end = (char*)&var + sizeof(var) - 1 ; 

Une macro appropriée pour afficher ces informations peut être:

 #define SHOW_ADDRESS_RANGE( var ) printf( #var"\t %p - %p %u bytes.\n", &var, (char*)&var + sizeof(var) - 1 , sizeof(var) ) 

Par exemple le code de test suivant:

 #include  #define SHOW_ADDRESS_RANGE( var ) printf( #var"\t %p - %p %u bytes.\n", &var, (char*)&var + sizeof(var) - 1 , sizeof(var) ) int a_global_int ; int main(void) { static a_static_int ; char char_array_10[10] ; int int_array_16[16] ; int integer ; char character ; long long long_long ; struct { int x ; int y ; char array[10] ; } a_structure ; SHOW_ADDRESS_RANGE( a_global_int ) ; SHOW_ADDRESS_RANGE( a_static_int ) ; SHOW_ADDRESS_RANGE( char_array_10 ) ; SHOW_ADDRESS_RANGE( int_array_16 ) ; SHOW_ADDRESS_RANGE( integer ) ; SHOW_ADDRESS_RANGE( character ) ; SHOW_ADDRESS_RANGE( long_long ) ; SHOW_ADDRESS_RANGE( a_structure ) ; return 0; } 

Sorties (par exemple, vos adresses seront probablement différentes, tout comme la taille des types de données et l’alignement et l’emballage de la structure):

 a_global_int 0x8049948 - 0x804994b 4 bytes. a_static_int 0x8049944 - 0x8049947 4 bytes. char_array_10 0xbf856502 - 0xbf85650b 10 bytes. int_array_16 0xbf856520 - 0xbf85655f 64 bytes. integer 0xbf8564f4 - 0xbf8564f7 4 bytes. character 0xbf8564f3 - 0xbf8564f3 1 bytes. long_long 0xbf8564f8 - 0xbf8564ff 8 bytes. a_structure 0xbf85650c - 0xbf85651f 20 bytes. 

À la lumière des commentaires, il semble que vous demandiez quelque chose de différent de celui abordé dans ma réponse ci-dessus:

L’allocation de données statiques est connue au moment de la construction et peut être signalée par votre éditeur de liens dans le fichier map. Un processus multithread a une stack par thread et les stacks de threads peuvent être allouées à partir du tas au moment de l’exécution. Les adresses de l’éditeur de liens seront des décalages par rapport à l’adresse de chargement du processus, qui est déterminée au moment de l’exécution par le chargeur du système d’exploitation. Dans un OS de bureau ou de serveur moderne, les adresses elles-mêmes sont virtuelles plutôt que physiques. Les détails sont spécifiques à la plate-forme, les détails précis pour Unix peuvent différer de ce que j’ai décrit.

Comment puis-je imprimer / trouver les plages d’adresses pour tous les types de variables (globales, locales, statiques, etc.).

Les variables locales sont généralement stockées sur la stack, ce qui signifie qu’elles ont une adresse différente à chaque appel de la fonction, et aucune adresse entre les appels de fonction ou dans les registres, ce qui signifie qu’ils n’ont pas d’adresse du tout.

Les variables globales et statiques sont fondamentalement la même chose après la création de l’éditeur de liens. Ils peuvent avoir une adresse fixe ou un décalage fixe par rapport à une adresse de segment uniquement disponible à l’exécution, ou une entrée dans une table de déplacement non spécifiée avant l’exécution. Sur certaines plates-formes Unix, les objects spécifient les adresses de base par défaut (ou adresses de base par segment) et ne sont déplacés que s’ils entrent en conflit avec autre chose (les exécutables ne sont généralement pas déplacés, les bibliothèques partagées); sur d’autres plates-formes, tout est toujours déplacé, quoi qu’il arrive (en tant que dispositif de sécurité).

De plus, les variables peuvent avoir ou non des symboles publics, selon la manière dont vous avez compilé et lié un programme ou un object partagé. Si c’est le cas, vous pouvez généralement rechercher l’adresse address / offset / relocation à l’aide d’un outil qui fait partie de votre chaîne d’outils de compilation, comme nm ou objtool ; S’ils ne le font pas, il n’y a rien à regarder.

Les plages sont-elles définies par une norme

Pas de norme Unix (ou POSIX / SuS). Si vous posez des questions sur une plate-forme plus spécifique, comme Linux avec glibc2.3 + sur x86_64 en utilisant l’ABI standard, il pourrait y avoir une réponse partielle, mais cette réponse sera différente pour chaque plate-forme.

ou puis-je les obtenir avec un outil ou avec une commande bash

Il n’y a pas de commande bash intégrée, mais, comme mentionné ci-dessus, votre combinaison de plate-forme et d’outils de compilation peut avoir un outil qui vous permet d’obtenir certaines des informations que vous souhaitez.

Lorsque vous liez votre application, vous devez créer un fichier de mappage de l’éditeur de liens. Le commutateur pour cela dépend de l’éditeur de liens que vous utilisez. Cela montrera comment la mémoire a été allouée.