Вопрос о структуре памяти процесса Linux - PullRequest
4 голосов
/ 06 июля 2011

Я говорю о 32-битной платформе Intel. Ядро Linux версии 2.6.31-14.

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

int init_global_var = 10;        /* Initialized global variable */
int global_var;                  /* Uninitialized global variable */
static int init_static_var = 20; /* Initialized static variable in global scope */
static int static_var;           /* Uninitialized static variable in global scope */

int main(int argc, char **argv, char **envp)
{
        static int init_static_local_var = 30;   /* Initialized static local variable */
    static int static_local_var;             /* Uninitialized static local variable */
    int init_local_var = 40;                 /* Initialized local variable */
    int local_var;                           /* Uninitialized local variable */
    char *dynamic_var = (char*)malloc(100);  /* Dynamic variable */

    printf("Address of initialized global variable: %p\n", &init_global_var);
    printf("Address of uninitialized global variable: %p\n", &global_var);
    printf("Address of initialized static variable in global scope: %p\n", &init_static_var);
    printf("Address of uninitialized static variable in global scope: %p\n", &static_var);
    printf("Address of initialized static variable in local scope: %p\n", &init_static_local_var);
    printf("Address of uninitialized static variable in local scope: %p\n", &static_local_var);
    printf("Address of initialized local variable: %p\n", &init_local_var);
    printf("Address of uninitialized local variable: %p\n", &local_var);
    printf("Address of function (code): %p\n", &main);
    printf("Address of dynamic variable: %p\n", dynamic_var);
    printf("Address of environment variable: %p\n", &envp[0]);
    char* p=0x0;
    printf("%s\n",p);

    exit(0);
}

Выход:

naman@naman-laptop ~> ./a.out
Address of initialized global variable: 0x804a020
Address of uninitialized global variable: 0x804a03c
Address of initialized static variable in global scope: 0x804a024
Address of uninitialized static variable in global scope: 0x804a034
Address of initialized static variable in local scope: 0x804a028
Address of uninitialized static variable in local scope: 0x804a038
Address of initialized local variable: 0xbfc11cbc
Address of uninitialized local variable: 0xbfc11cb8
Address of function (code): 0x8048484
Address of dynamic variable: 0x8223008
Address of environment variable: 0xbfc11d7c
fish: Job 1, “./a.out” terminated by signal SIGSEGV (Address boundary error)

В приведенном выше коде у меня следующая путаница. Почему код лежит на 0x8048484, а не где-то близко к началу виртуальной памяти, например, 0x00000400? Насколько я знаю, раскладка должна быть такой:

Недостаточно памяти ........................................ HighMemory

Text Data BSS Heap.....................Stack Env

Итак, текст не должен лежать так глубоко в памяти. Это должно быть близко к нижней памяти, не так ли?

Ответы [ 2 ]

5 голосов
/ 06 июля 2011

Почему код лежит в 0x8048484

Поскольку адрес загрузки по умолчанию (начало файла ELF будет загружено по этому адресу) равен 0x8000000 (или 0x8048000). Это значение по умолчанию исправлено в скрипте компоновщика по умолчанию (ld) и может быть изменено с помощью параметров компоновщика.

Обратите внимание, что это 0x08000000 или 0x08048000 (128 мегабайт), а не 0x80000000 (2 гигабайта).

Здесь обсуждается этот предел http://cboard.cprogramming.com/tech-board/101129-why-address-space-0-0x08000000-process-unused.html на форумах и http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA111&lpg=PA111&dq=linker+0x08000000 в книгах. Также http://lkml.org/lkml/2002/2/20/194 в lkml с хорошим описанием:

"0x8048000 является типичной отправной точкой для текстового сегмента в соответствии с к спецификации System V Intel 386 ABI (http://stage.caldera.com/developer/devspecs/abi386-4.pdf)."

0 голосов
/ 06 июля 2011

Когда a.out не a.out?Когда это на самом деле ELF.Попробуйте elfinfo --all a.out для деталей.

...