Что такое разрыв программы? Откуда это начинается,0x00?
int brk(void *end_data_segment);
void *sbrk(intptr_t increment);
Вызов sbrk() с шагом 0 может быть использован для определения текущего местоположения остановки программы.
Что такое разрыв программы? Откуда это начинается,0x00?
5 ответов
Прерывание программы - это конец сегмента данных процесса. AKA...
разрыв программы - это первая позиция после окончания сегмента неинициализированных данных
Что касается того, откуда он начинается, он зависит от системы, но, вероятно, не 0x00.
Упрощаю:
Процесс имеет несколько сегментов памяти:
- Код (текст) сегмент, который содержит код для выполнения.
- Сегмент данных, который содержит данные, о которых знает компилятор (глобальные переменные и статика).
- Сегмент стека, который содержит (барабанную дробь...) стопку.
(Конечно, в настоящее время все гораздо сложнее. Есть сегмент родата, сегмент неинициализированных данных, сопоставления, выделенные через mmap, vdso, ...)
Один из традиционных способов, которым программа может запрашивать больше памяти в Unix-подобной ОС, заключается в увеличении размера сегмента данных и использовании распределителя памяти (т.е. malloc()
реализация) для управления полученным пространством. Это делается через brk()
системный вызов, который изменяет точку, в которой сегмент данных "ломается" / заканчивается.
В эти дни sbrk (2) (и brk
) являются почти устаревшими системными вызовами (и вы можете почти забыть о них и проигнорировать старое понятие break; сосредоточиться на понимании mmap (2)). Обратите внимание, что sbrk (2) man
Страница говорит в своих примечаниях:
Избегать использования
brk()
а такжеsbrk()
: пакет выделения памяти malloc (3) - это портативный и удобный способ выделения памяти.
(акцент мой)
Большинство реализаций malloc (3) (особенно в http://musl-libc.org/) скорее используют mmap (2), чтобы требовать память - и увеличивать свое виртуальное адресное пространство - от ядра (посмотрите на эту виртуальную адресную страницу википейдж, у нее есть хороший картина). Немного malloc
использование sbrk
для небольших ассигнований, mmap
для больших.
Используйте strace (1), чтобы узнать системные вызовы (перечисленные в syscalls (2)), выполняемые каким-либо заданным процессом или командой. Кстати, тогда вы найдете, что bash
а также ls
(и, вероятно, многие другие программы) не делать ни одного звонка sbrk
,
Исследуйте виртуальное адресное пространство какого-либо процесса с помощью proc (5). Пытаться cat /proc/$$/maps
а также cat /proc/self/maps
и даже cat /proc/$$/smaps
и прочитайте немного, чтобы понять вывод.
А также sbrk
не очень дружественный поток.
(мой ответ сосредоточен на Linux)
Вы говорите, что sbrk() - это системный системный вызов и что мы должны использовать malloc (), но malloc (), согласно ее документации, когда выделяется меньше памяти, чем 128 КиБ (32 страницы). Таким образом, мы не должны использовать sbrk() напрямую, но malloc () использует его, если выделение больше 128 КиБ, тогда malloc () использует mmap (), который распределяет частные страницы в пространстве пользователя. Наконец, это хорошая идея для понимания sbrk(), по крайней мере, для понимания концепции "Разрыв программы".
На основе следующей широко используемой схемы:
, который также известен какbrk
во многих статьях указывает на адрес конца сегмента кучи.
Когда вы звонитеmalloc
, он меняет адресprogram break
.