Сколько страниц памяти компиляторы C в настольных ОС используют для обнаружения переполнения стека? - PullRequest
7 голосов
/ 04 апреля 2011

Этот вопрос имеет отношение к этому , касающемуся массивов переменной длины в C99, но отличается от него.

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

Современные не встроенные платформы компиляции используют недопустимыйЗона памяти для обнаружения некоторых переполнений стека без дополнительных затрат (проверки - это только проверки, уже сделанные MMU бесплатно).Это не защищает на 100% от вышеуказанной проблемы, потому что очень большой локальный массив может заставить указатель стека перепрыгнуть через недопустимую область.

Кто-нибудь знает, сколько страниц обычно выделяется для этого обнаружения?Я думаю, это будет по крайней мере 4 КБ, но это может быть больше.Это выбор, сделанный компилятором или ОС, и в любом случае, есть ли способ изменить его?

Ответы [ 2 ]

7 голосов
/ 04 апреля 2011

Я почти уверен, что наиболее распространенной практикой является использование только одной страницы, обычно 4k. Хороший компилятор, однако, будет последовательно пытаться получить доступ к каждой странице кадра стека, превышающей размер страницы при входе в функцию (или при выделении VLA / alloca), чтобы обеспечить попадание на защитную страницу. GCC может при желании сделать это; см .: http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options и опция -fstack-check.

6 голосов
/ 04 апреля 2011

В Windows это одна страница размером 4 КБ (по крайней мере, на x86): см. Описание проверки стека для приложений на базе Windows NT .

Этот метод автоматического роста используетзащитная страница, зарезервированная, незафиксированная, страница памяти, которая смежна с выделенной частью памяти.Когда приложение касается страницы защиты, операционная система фиксирует эту страницу, и следующая незафиксированная страница становится новой страницей защиты.Автоматический рост стека работает только для защитной страницы, а объем стека должен увеличиваться с шагом 4 КБ или одной страницы.Если приложение касается другой зарезервированной, но незафиксированной страницы стековой памяти, прежде чем оно коснется страницы защиты, возникает обычное исключение сбоя страницы, что может привести к непредсказуемому поведению.

...

Чтобы предотвратить ошибку, компилятор вызывает функцию __chkstk () каждый раз, когда локальное распределение превышает 4K.Функция Windows NT __chkstk () явно не проверяет переполнение стека, как в версии MS-DOS.Он просто касается адресов памяти каждые 4K от текущего местоположения указателя стека до запрошенного выделения.Это вызывает защитные страницы в правильной последовательности и фиксирует дополнительную память в стеке при необходимости.

Для GCC, Проверка стека GCC

Я неуверен, как / если VLA C99 изменит поведение WinNT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...