Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: переполнения стека, когда глубина рекурсии неизвестна  (Прочитано 21672 раз)
0 Пользователей и 1 Гость смотрят эту тему.
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« : 12-08-2011 20:17 » 

можно ли (если да, то как) узнать, что при вызове след. функции или при входе в след. блок произойдет переполнение стека?
//кроме как суммировать sizeof всех переменных (и адресов возврата, что записываются в сек перед вызовом ф-ции)
или как-нибудь перехватить это исключением?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 12-08-2011 20:19 » 

А если переписать алгоритм на итеративный?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 12-08-2011 20:22 » 

не, а если не переписывать
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 12-08-2011 20:34 » 

FeelUs, Проверять значение регистра ESP. В нем содержится текущее смещение в стеке.
Записан

Любимая игрушка - debugger ...
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 12-08-2011 20:38 » 

О, точно, спасибо, а как его получить, и с чем сравнивать?
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 12-08-2011 20:45 » 

FeelUs,
Ну например можно так получить:
Код: (C++)
unsigned int esp_val;

_asm {
    mov esp_val, esp
};
Только я бы на твоем месте не возился с размером стека, т.к. его размер определяется реализацией операционной системы и может меняться от версии к версии. Лучше перепиши алгоритм... Улыбаюсь
Записан

Любимая игрушка - debugger ...
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 13-08-2011 05:46 » 

т.е. размер стека определяется не на этапе компиляции а на этапе выполнения?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #7 : 13-08-2011 06:12 » 

На этапе линковки можно задать параметр, который будет определять минимальный размер стека для программы. А реальный размер стека определяется ОС.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 13-08-2011 06:47 » 

а вообще операционная система ведь проверяет, не обратилась ли программа к нетой области памяти, не переполнился ли у нее стек, зачем она заставляет программу делать тоже самое ещё раз? Здесь была моя ладья...
//наверно, она предполагает, что программа не должна делать проверку еще раз и при этом у нее не должны случаться такие ситуации...
неужели она не может, если заметила подобное поведение у программы, не аварийно закрывать ее, а как-нибудь сообщить об этом в программу?
//я конечно понимаю, что все это довольно сложно, и врядли такое есть в винде, но может это есть в других ОС? :Улыбаюсь

а кстати что за параметр (в MSVC2008)?
или чему он равен по умолчанию?
« Последнее редактирование: 13-08-2011 06:55 от FeelUs » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #9 : 13-08-2011 06:55 » 

FeelUs, Что то ты сумбурно пишешь. Такое ощущение, что разговариваешь сам с собой.

Добавлено через 3 минуты и 54 секунды:
Вот параметр для установки минимального требуемого размера стека для программы.
http://msdn.microsoft.com/en-us/library/8cxs58a6(v=vs.80).aspx
« Последнее редактирование: 13-08-2011 06:59 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 13-08-2011 06:59 » 

прям порассуждать нельзя Что, съел?
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 13-08-2011 07:27 » 

FeelUs, Если бы операционные системы отслеживали стек, то одной из самых коварных уязвимостей типа "Переполнение стека (переполнение буфера размещенного в стеке)" просто не существовало. Но чтобы реализовать проверку на переполнение стека потребовалось бы проверять каждую попытку программы выделить память в стеке. А это происходит настолько часто, что любая даже самая простейшая проверка превратит современный компьютер в доисторический калькулятор... И по этому память в стеке выделяется и освобождается всего одной командой процессора:
Код: (ASM)
mov eax, 4 ;поместили в регистр eax число 4
push eax ;выделили в стеке 4 байта
pop eax ;освободили в стеке 4 байта
Записан

Любимая игрушка - debugger ...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #12 : 13-08-2011 08:07 » 

RuNTiME, Частично не верно Улыбаюсь ОС отслеживает переполнение стека в целом. Т.е Вышел ли указатель вершины стека за пределы пула стека. А что творится внутри пула стека ОС никак не волнует. Это дело лежит полностью на совести программиста.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
FeelUs
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 13-08-2011 09:46 » 

правильно, при выполнении push eax; не переполнился ли стек проверяет процессор , и если переполнение произошло, происходит прерывание (или что-то вроде того) и управление передается ОС
(т.е. это поддерживается аппаратно)
иначе как ОС понимает, что произошло переполнение стека или обращение к нетой ячейке памяти чтобы закрыть программу
Записан
RuNTiME
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 13-08-2011 10:02 » 

Finch, FeelUs, точно - точно, подзабыл  нюансы работы ОС с памятью. Вспомнил тут про Structured Exception Handling. С его помощью можно ловить те самые исключения, которые генерирует ОС на прерывание переполнения. Почитать об этом можно тут: http://www.insidepro.com/kk/014/014r.shtml
« Последнее редактирование: 13-08-2011 10:07 от RuNTiME » Записан

Любимая игрушка - debugger ...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #15 : 13-08-2011 10:48 » 

Переполнение отслеживается на уровне страниц. Система никак это не проверяет, пока не "стрельнет".
http://wm-help.net/books-online/book/59464/59464-9.html
Немного старо, но принцип тот же.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 13-08-2011 16:22 » 

Не знаю, что там в винде, а насчет Линукса мы еще семь лет назад разбирали: в конце стековой области процесса имеется специальная страница, при записи в которую происходит исключение и ядро выделяет еще одну страницу. Максимальный размер стека регулируется лимитами.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #17 : 13-08-2011 16:43 » 

Не знаю, что там в винде, а насчет Линукса мы еще семь лет назад разбирали: в конце стековой области процесса имеется специальная страница, при записи в которую происходит исключение и ядро выделяет еще одну страницу. Максимальный размер стека регулируется лимитами.
А если кто-то решит передать большой объект по значению? Размером, этак, в 8К. Копировать его компилятор будет, естественно, с младших адресов...
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 13-08-2011 16:47 » new

PredatorAlpha, если очень интересно - загляни в исходники ядра Линукс. Я это делал давно (тогда - 7 лет назад) и всю полноту картины не помню. А еще проще - написать тест по твоим условиям. Думаю, он сработает.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines