Как операционная система обнаруживает переполнение стека? - PullRequest
3 голосов
/ 07 февраля 2011

Во многих операционных системах стек и куча начинаются с противоположных сторон виртуального адресного пространства процесса и растут навстречу друг другу.Это позволяет стеку максимально расширяться без попадания в кучу.

Предположим, у меня есть программа, которая вызывает переполнение стека.Мое текущее понимание состоит в том, что это приведет к тому, что стек будет бесконтрольно расти в направлении кучи и в конечном итоге попадать в нее.Это правильно?Если это так, как операционная система обнаруживает переполнение стека?Похоже, ОС не сможет обнаружить, что программа пытается использовать виртуальную память, выделенную для кучи, как часть стека, так как они находятся в смежных областях памяти.

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

Ответы [ 4 ]

4 голосов
/ 07 февраля 2011

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

2 голосов
/ 07 февраля 2011

Это просто интуиция, но уверенность в том, что стек не мешает куче, звучит как работа JVM.Я не вижу причин, по которым я не смог создать свой собственный ужасный язык программирования, в котором стек позволял перезаписывать кучу (до сбоя).

1 голос
/ 07 февраля 2011

Большинство современных процессоров имеют MMU (модуль управления памятью), и это «аппаратное» устройство для применения виртуального адреса к каждой программе, и каждая программа живет в своем собственном пространстве памяти. ОС обрабатывает этот MMU, и когда программа хочет прочитать или записать адрес из выделенной памяти, MMU вызывает прерывание.

http://en.wikipedia.org/wiki/Memory_management_unit

Таким образом, довольно странно, как он может обнаружить SO. Стек и куча не находятся на непрерывных адресах памяти.

Я также видел другой подход, использующий защитные слова. Стек для каждого процесса был выделен в куче и заполнен подопечными (что-то вроде 0xc0cac01a). Таким образом, было легко получить размер стека для каждого процесса, просто посчитав защитные слова. Операционная система вызвала панику, если не было хотя бы одного защитного слова.

1 голос
/ 07 февраля 2011

Переполнения стека возвращаются в стек в обратном направлении - они работают путем перезаписи данных в уже инициализированных частях стека, что возможно именно потому, что стеки растут вниз.

Таким образом, операционная система не может обнаружить это условие, поскольку процессу разрешено изменять инициализированные части своего стека в любое время.

Расширение стека выполняется процессом, использующим пространство стека, и ОС, попадающая в обработчик ошибок страницы, потому что ни одна страница не была настроена. Некоторые ОС допускают такой доступ только на «защитной странице», то есть страница непосредственно перед текущим стеком будет инициировать перераспределение, другие смотрят на содержимое регистра указателя стека во время сбоя, чтобы увидеть, должно ли это быть. доступ к стеку.

...