Почему я вижу несколько одинаковых сегментов в выводе /proc/pid/maps?

Тест на 32-битной Linux

Код выглядит следующим образом:

int foo(int a, int b)
{
    int c = a + b;
    return c;
}

int main()
{
    int e = 0;
    int d = foo(1, 2);
    printf("%d\n", d);
    scanf("%d", &e);

    return 0;
}

и когда я использую cat /proc/pid/maps для просмотра схемы памяти, кажется, что я вижу три сегмента text для своего кода и библиотеки.

ubuntu% cat /proc/2191/maps
08048000-08049000 r-xp 00000000 08:01 1467306    /home/shuai/work/asm/test1
08049000-0804a000 r--p 00000000 08:01 1467306    /home/shuai/work/asm/test1
0804a000-0804b000 rw-p 00001000 08:01 1467306    /home/shuai/work/asm/test1
09137000-09158000 rw-p 00000000 00:00 0          [heap]
b75c6000-b75c7000 rw-p 00000000 00:00 0
b75c7000-b776b000 r-xp 00000000 08:01 3149924    /lib/i386-linux-gnu/libc-2.15.so
b776b000-b776d000 r--p 001a4000 08:01 3149924    /lib/i386-linux-gnu/libc-2.15.so
b776d000-b776e000 rw-p 001a6000 08:01 3149924    /lib/i386-linux-gnu/libc-2.15.so
b776e000-b7771000 rw-p 00000000 00:00 0
b7780000-b7784000 rw-p 00000000 00:00 0
b7784000-b7785000 r-xp 00000000 00:00 0          [vdso]
b7785000-b77a5000 r-xp 00000000 08:01 3149914    /lib/i386-linux-gnu/ld-2.15.so
b77a5000-b77a6000 r--p 0001f000 08:01 3149914    /lib/i386-linux-gnu/ld-2.15.so
b77a6000-b77a7000 rw-p 00020000 08:01 3149914    /lib/i386-linux-gnu/ld-2.15.so
bfd47000-bfd68000 rw-p 00000000 00:00 0          [stack]

Может ли кто-нибудь дать мне руководство по этому вопросу? Большое тебе спасибо!


person lllllllllllll    schedule 22.12.2013    source источник


Ответы (2)


Обратите внимание на значения в столбцах 3 (начальное смещение) и 2 (разрешения). На самом деле у вас есть одна и та же часть, отображенная дважды, в строках 1 и 2 для вашего двоичного файла, но в строке 3 все по-другому. Разрешается отображать один и тот же файл отдельно несколько раз; разные системы могут не объединять это в одну запись карты VM, поэтому она может отражать историю сопоставления, но не текущее состояние jist.

Если вы посмотрите на сопоставления библиотек, вы можете легко найти закон о том, что любая библиотека отображается отдельно:

  • С разрешением на чтение и выполнение: основной код, который нельзя изменять.
  • С разрешением на чтение: разрешена область постоянных данных без кода.
  • С разрешением на чтение и запись: сочетает непостоянную область данных и таблицы перемещения общих объектов.

Дважды отображаемая одна и та же начальная область двоичного файла размером 4 КБ может быть объяснена логикой RTLD, которая отличается от логики произвольной библиотеки из-за необходимости начальной загрузки. Я не отношусь к этому так важно, тем более что он может легко отличаться в зависимости от платформы.

person Netch    schedule 22.12.2013

Обратите внимание, что три раздела для каждого файла имеют разные разрешения: только чтение, чтение-запись и чтение-выполнение. Это сделано для безопасности: часть кода (чтение-выполнение) не может быть записана с помощью эксплойтов, а часть, которая может быть записана, не может быть выполнена.

person nobody    schedule 22.12.2013