Ваш вопрос охватывает много совершенно разных вещей, поэтому ответ будет длинным.
Первый вопрос - это значение
7fcc37491000-7fcc37691000 ---p 001ba000 08:01 1053757 /lib/x86_64-linux-gnu/libc-2.19.so
в
7fcc372d7000-7fcc37491000 r-xp 00000000 08:01 1053757 /lib/x86_64-linux-gnu/libc-2.19.so
7fcc37491000-7fcc37691000 ---p 001ba000 08:01 1053757 /lib/x86_64-linux-gnu/libc-2.19.so
7fcc37691000-7fcc37695000 r--p 001ba000 08:01 1053757 /lib/x86_64-linux-gnu/libc-2.19.so
7fcc37695000-7fcc37697000 rw-p 001be000 08:01 1053757 /lib/x86_64-linux-gnu/libc-2.19.so
Эта недоступная область памяти представляет собой промежуток между смежными сегментами ELF библиотеки (который должен занимать непрерывный кусок памяти).Режим защиты ---p
запрещает использовать этот пробел для случайного выделения памяти.Если вы strace(1)
выполняете процесс при загрузке библиотеки, вы можете увидеть что-то вроде этого:
mmap(NULL, 1848896, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3</usr/lib/libc-2.28.so>, 0) = 0x7f9673d8f000
mprotect(0x7f9673db1000, 1671168, PROT_NONE) = 0
mmap(0x7f9673db1000, 1355776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc-2.28.so>, 0x22000) = 0x7f9673db1000
mmap(0x7f9673efc000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc-2.28.so>, 0x16d000) = 0x7f9673efc000
mmap(0x7f9673f49000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc-2.28.so>, 0x1b9000) = 0x7f9673f49000
Первый mmap()
отображает первый сегмент ELF в память, но резервирует пространство для вся библиотека.Это сделано для того, чтобы ядро могло выбирать расположение библиотеки на свое усмотрение.Для защиты любых возможных промежутков между сегментами mprotect(..., PROT_NONE)
вызывается;затем все оставшиеся сегменты отображаются в память с помощью mmap()
- это также изменяет режим защиты соответствующих страниц памяти с ---p
на любой режим, который требуется сегменту.Вы можете повеселиться, посмотрев , как это на самом деле работает .Если вы хотите проверить, как образовался этот разрыв ---p
во время загрузки, вы также можете использовать readelf(1)
с двоичным файлом библиотеки и выполнить некоторую шестнадцатеричную математику с расположением и выравниванием сегментов, сопоставляя результаты с выводом strace
.
Второй вопрос - это следующие анонимные сопоставления:
7fcc36ad6000-7fcc36ad7000 ---p 00000000 00:00 0
7fcc36ad7000-7fcc372d7000 rw-p 00000000 00:00 0
Это похоже на стек потоков для thread 1
.Вторым отображением является сам стек (372d7000
- 36ad7000
= 800000
= 8 МБ, который является пределом размера стека по умолчанию во многих дистрибутивах, который, в свою очередь, является размером стека по умолчанию для pthread
),и первая страница является защитной страницей.Эта страница в режиме ---p
защищает стек от переполнения и запускает segfault, когда происходит переполнение (из-за записи на эту защищенную от записи страницу).
Примечание: в старых ядрах Linux поток складываетсябыли помечены [stack:TID]
именами в maps
файле, но эта функция была удалена, поэтому я не могу гарантировать , что это отображение действительно является стеком потоков (хотя выглядит так).Однако вы можете использовать strace
, чтобы найти точное расположение стека потока из аргумента child_stack
системного вызова clone()
и сравнить с этим отображением.
Продолжаем. Третий вопрос :
7fcc30000000-7fcc30021000 rw-p 00000000 00:00 0
7fcc30021000-7fcc34000000 ---p 00000000 00:00 0
Что ж, это то, что malloc()
в thread 1
сделал, чтобы выделить запрошенную вами память.Короче говоря, весь регион 7fcc30000000-7fcc34000000
представляет собой кучу , из которой выполняются выделения.Интервал rw-p
7fcc30000000-7fcc30021000
, выделенный из этой кучи, будет расти по мере того, как вы будете запрашивать все больше и больше памяти с помощью malloc()
.Когда эта куча будет исчерпана, будет запрошена новая, используя mmap()
.
Как вы, вероятно, заметили, у меня нет объяснения для следующих отображений в вашем вопросе:
7fcc37abe000-7fcc37ac1000 rw-p 00000000 00:00 0
7fcc37ad8000-7fcc37adc000 rw-p 00000000 00:00 0
Я не могу быстро распознать этих парней и не уверен, что это обычное распределение.Вероятно, это требует отдельного исследования, так как эта тема уже слишком длинная.