Что такое сегмент данных c / c ++ и размер стека?

Я читал, что это зависит от архитектуры компилятора и операционной системы. Как узнать максимальный размер сегмента данных и стека в системе Linux, используя GCC в качестве компилятора?

3

Решение

Позвольте мне поэкспериментировать с вами: создайте файл « test.c » следующим образом:

int main (void) { return 0; }

Теперь скомпилируйте его, указав максимальный размер стека (просто для поиска этого числа в файле карты и определения имени символа, ссылаясь на него):

gcc test.c -o test.x -Wl,--stack=0x20000 -Wl,-Map=output.map

Определить размер данных просто:

size -A -d test.x

Вы получите что-то вроде этого:

section           size         addr
.text             1880   4299165696
.data              104   4299169792
...

Также « objdump -h test.x » будет работать нормально, но с менее подробными результатами.

Здесь есть больше разделов (не только код и данные), но здесь нет информации о стеке. Зачем? Поскольку размер стека не является разделом ELF, он зарезервирован только после загрузки вашей программы для выполнения. Вы должны прочитать его из некоторого (зависимого от платформы) символа в вашем файле, например:

$ nm test.x  | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__

Не удивительно, что этот размер равен 0x20000, как было указано при компиляции.

Я определил имя символа, посмотрев в файл output.map, который был сгенерирован во время компиляции. Я также рекомендую начать с рассмотрения.

Далее, когда у вас есть какой-то неизвестный файл a.out, просто повторите последовательность:

size -A -d a.out
nm a.out | grep __size_of_stack_reserve__

Подставляя платформо-зависимый символ этому, вы определили в эксперименте, описанном выше.

4

Другие решения

Сегменты — это метод организации вещей, которые нужны вашему исполняемому файлу.

Сегмент данных обычно предназначен для любых данных, которые использует ваш исполняемый файл (без ввода из внешних источников). Некоторые сегменты данных могут содержать строковые литералы или числовые константы.

Многие исполняемые файлы используют стек для хранения локальных переменных функций, локальных переменных блоков операторов, адресов возврата и параметров функций. Стек не требуется языками C или C ++; это просто удобная структура данных.

размер стека может быть либо емкость, выделенная стеку, либо количество элементов, находящихся в стеке, либо объем памяти, занимаемый стеком.

Многие платформы имеют размер по умолчанию для стека. Поскольку платформы различаются, вам необходимо прочитать документацию по своим инструментам, чтобы узнать, как установить размер стека и какова емкость по умолчанию.

3

Как узнать максимальный размер сегмента данных и стека в системе Linux, используя GCC в качестве компилятора?

Эти пределы можно прочитать как RLIMIT_DATA а также RLIMIT_STACK пределы ресурса getrlimit.

В командной строке вы можете использовать ulimit Команда, чтобы найти эти ограничения вашей системы:

$ ulimit -s # stack
8515
$ ulimit -d # data
unlimited

Вы можете изменить системные ограничения, изменив limits.conf.

И еще в man pthread_create:

В Linux / x86-32 размер стека по умолчанию для нового потока составляет 2 мегабайта. Согласно реализации многопоточности NPTL, если ограничение мягкого ресурса RLIMIT_STACK во время запуска программы имеет какое-либо значение, отличное от «unlimited», то оно определяет размер стека по умолчанию для новых потоков. Используя pthread_attr_setstacksize (3), атрибут размера стека может быть явно установлен в аргументе attr, используемом для создания потока, чтобы получить размер стека, отличный от значения по умолчанию.

И в man ld:

—стек резерв

—резервировать стек, фиксировать

Укажите количество байтов памяти, которые нужно зарезервировать (и при необходимости зафиксировать) для использования в качестве стека для этой программы. По умолчанию зарезервировано 2 МБ, зафиксировано 4 КБ. [Эта опция специфична для целевого порта i386 PE компоновщика]

0
По вопросам рекламы [email protected]