Savoir si un pointeur pointe sur la stack, le tas ou le texte du programme?

Existe-t-il un moyen de savoir si un pointeur pointe vers un emplacement dans:

  • la stack
  • le tas
  • ou le programme (et si oui, quelle section, par exemple elf .text)?

Cela peut-il aussi être fait de manière portable (Linux 64/32 bits, OSX et Windows 7+)?

suivre:

Je ne cherche pas à savoir si quelque chose a été mallocé.

Je souhaite distinguer efficacement les pointeurs vides * vers les fonctions du programme des pointeurs vides * aux données de la stack ou du tas.

Ceci est pour un environnement de langage écrit en C, pas un programme en C “normal”.

Cette réponse a été la plus utile jusqu’à présent: Vérifier si quelque chose a été mallocé

Vous ne pouvez pas faire ce que vous voulez de manière portable, car la norme de langage C ne spécifie pas la stack, la zone de programme et le segment de mémoire en tant que zones distinctes. Leur emplacement peut dépendre de l’architecture du processeur, du système d’exploitation, du chargeur, de l’éditeur de liens et du compilateur. Essayer de deviner où un pointeur pointe est en train de casser l’abstraction fournie par C, alors vous ne devriez probablement pas le faire.

Néanmoins, il existe des moyens d’écrire du code permettant de deviner correctement un environnement spécifique. Pour ce faire, vous examinez les adresses des objects existants et recherchez des modèles. Considérez le programme suivant.

 #include  #include  void function() { int stack2; printf("stack2: %15p\n", &stack2); } int main(int argc, char *argv[]) { int stack; void *heap = malloc(1); void *heap2 = malloc(1); printf("program: %15p\n", main); printf("heap: %15p\n", heap); printf("heap2: %15p\n", heap2); printf("stack: %15p\n", &stack); function(); return 0; } 

En examinant sa sortie, vous pouvez voir un motif, tel que le suivant sur Linux x64.

 program: 0x400504 heap: 0x1675010 heap2: 0x1675030 stack: 0x7fff282c783c stack2: 0x7fff6ae37afc 

A partir de ce qui précède, vous pouvez déterminer que (probablement) le segment de mémoire grandit à partir de 0x1675010, le code de programme (ou des données statiques, que vous n’avez pas mentionnées) se trouve en dessous, et que la stack croît de manière imprévisible (probablement en raison de la stack). randomisation) autour d’une très grande adresse, comme 0x7fff282c783c.

Comparez cela avec la sortie sous Intel Linux 32 bits:

 program: 0x804842f heap: 0x804b008 heap2: 0x804b018 stack: 0xbf84ad38 stack2: 0xbf84ad14 

Microsoft Windows et le compilateur Microsoft C 32 bits:

 program: 01271020 heap: 002E3B00 heap2: 002E3B10 stack: 0024F978 stack2: 0024F964 

gcc sous Windows Cygwin:

 program: 0040130B heap: 00A41728 heap2: 00A417A8 stack: 0028FF44 stack2: 0028FF14 

gcc sous Intel 32 bits FreeBSD:

 program: 0x8048524 heap: 0x804b030 heap2: 0x804b040 stack: 0xbfbffb3c stack2: 0xbfbffb1c 

gcc sous Intel FreeBSD 64 bits:

 program: 0x400770 heap: 0x801006058 heap2: 0x801006060 stack: 0x7fffffffdaec stack2: 0x7fffffffdabc 

gcc sous SPARC-64 FreeBSD:

 program: 0x100860 heap: 0x40c04098 heap2: 0x40c040a0 stack: 0x7fdffffe9ac stack2: 0x7fdffffe8dc 

PowerPC sous MacOS X:

 program: 0x1ed4 heap: 0x100120 heap2: 0x100130 stack: 0xbffffba0 stack2: 0xbffffb38 

PowerPC sous Linux:

 program: 0x10000514 heap: 0x100c6008 heap2: 0x100c6018 stack: 0xbff45db0 stack2: 0xbff45d88 

StrongARM sous NetBSD:

 program: 0x1c5c heap: 0x5030 heap2: 0x5040 stack: 0xefbfdcd0 stack2: 0xefbfdcb4 

et ARMv6 sous Linux:

 program: 0x842c heap: 0xb63008 heap2: 0xb63018 stack: 0xbe83eac4 stack2: 0xbe83eaac 

Comme vous pouvez le constater, les possibilités sont infinies.

Vous pouvez déterminer l’emplacement en général de la stack et du tas, mais sa taille sera une autre histoire …

 void *heap_locations; void *stack_location; void determine_locations (int any_int) { free(heap_location = malloc(248)); stack_location = &any_int; } int main(int argc, char *argv[]) { determine_locations(argc); . . . return 0; } 

Un peu grossier et vous ne saurez pas quelle direction d’expansion ou quelle taille d’expansion, sauf s’il s’agit de plates-formes spécifiques.