2017-06-29 2 views
1

Je lisais quelque part que le tas commence juste après le segment BSS. J'ai essayé de le vérifier avec le code suivant et je me décharge de base (très probablement d'un accès mémoire illégale):Zone entre le segment BSS et le saut de programme (fin de segment)

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

extern char etext, edata, end; 

int main(int argc, char **arg, char **envp) { 
    printf("Size of virtual memory pages %ld\n", sysconf(_SC_PAGESIZE)); 

    printf("BSS segment ends at %p\n", &end); 
    printf("Program break (heap) ends at %p\n", sbrk(0)); 

    printf("Assuming segment above %p and below %p is heap\n", &end, sbrk(0)); 

    int *heap_ptr = (int *)sbrk(0); 
    //Subtract 40 bytes from heap end assuming heap is allocated 
    heap_ptr = heap_ptr - 10; 
    *heap_ptr = 21548; 

    printf("Reading value %d\n", *heap_ptr); 

    exit(EXIT_SUCCESS); 
} 

sortie de l'exécution:

Size of virtual memory pages 4096 
BSS segment ends at 0x601060 
Program break (heap) ends at 0x8da000 
Assuming segment above 0x601060 and below 0x8da000 is heap 
Segmentation fault (core dumped) 

Est-ce que cela signifie qu'il ya un ' trou 'entre la fin de BSS et le début de tas? Il semble qu'il n'y ait pas de pages de tas pré-allouées et qu'elles ne commencent pas juste après la fin du segment BSS.

Répondre

0

Tout cela dépend de votre système d'exploitation. Je vais supposer que vous utilisez Linux. La plupart des distributions sont livrées avec kernel.randomize_va_space = 2 qui randomise l'adresse du tas.

Vous pouvez imprimer la liste des adresses mappées dans votre programme en ajoutant

FILE *fd = fopen("/proc/self/maps", "r"); 
if (fd) { 
    char line[256]; 
    while (fgets(line, sizeof(line), fd)) { 
     printf("%s", line); 
    } 
    fclose(fd); 
} 

Si j'exécuter sur ma boîte, je reçois

Size of virtual memory pages 4096 
BSS segment ends at 0x601080 
Program break (heap) ends at 0x1f37000 
Assuming segment above 0x601080 and below 0x1f37000 is heap 
00400000-00401000 r-xp 00000000 00:28 383781510    /home/guillaume/f 
00600000-00601000 r--p 00000000 00:28 383781510    /home/guillaume/f 
00601000-00602000 rw-p 00001000 00:28 383781510    /home/guillaume/f 
01f16000-01f37000 rw-p 00000000 00:00 0      [heap] 

Vous voyez qu'il ya clairement un fossé entre la deux.

Cependant, si je lance sudo sysctl kernel.randomize_va_space=0, puis re-exécuter le programme

Size of virtual memory pages 4096 
BSS segment ends at 0x601080 
Program break (heap) ends at 0x623000 
Assuming segment above 0x601080 and below 0x623000 is heap 
00400000-00401000 r-xp 00000000 00:28 383781510     /home/guillaume/f 
00600000-00601000 r--p 00000000 00:28 383781510     /home/guillaume/f 
00601000-00602000 rw-p 00001000 00:28 383781510     /home/guillaume/f 
00602000-00623000 rw-p 00000000 00:00 0       [heap] 

Dans ce cas, il n'y a pas d'espace et votre programme ne pas segmentation fault.

0

Vous avez un malentendu de base de la mémoire. Tout d'abord, il peut y avoir plusieurs segments BSS après le chargement complet d'un exécutable. Deuxièmement, il peut y avoir plusieurs tas. Vous n'allez pas trouver THE tas après le segment BSS.