LINUX.ORG.RU

ulimit -s


0

0

Наивный вопрос.

Допустим, ulimit -s (под Башем) мне показывает некую цифру.

Она означает, что у программы, стартованной из-под этого Баша, стэк не может быть больше,чем это число.

А что РЕАЛЬНО определяет размер стэка?

Если оно (ulimit -s) равно 8192 K, означает ли это, что у моей прогаммы будет именно ТАКОЙ стэк?

★★★★★

Да, и еще:

Что произойдет с программой, которая попросила стэк, выхлдящий за пределы установленного ulimit -s ?

Сигнал какой ее убьет, или еще что?

Die-Hard ★★★★★
() автор топика

Придет армагедон в общем виде: Segmentation fault, кличка SIGSEGV.

anonymous
()

Насколько я знаю ето чтото типа значения по умолчанию. Твоя прога может запросить стек размером до ulimit -Hs. Ну а если создавть процессы при помощи clone то какой стек проге передаш такой и будет.

cvv ★★★★★
()
Ответ на: комментарий от Die-Hard

Если лимит выше ulimit -Hs то программа не запустится с руганью на недоступность ресурсов а если меньше ulimit -Hs но больше ulimit -Ss то скорее всего будет то что сказал ананимус.

cvv ★★★★★
()
Ответ на: комментарий от cvv

>Ну а если создавть процессы при помощи clone то какой стек проге передаш такой и будет.

Судя по man(лень лезть в исходный код) можно сделать void* stack = mmap(...MAP_ANONYMOUS|MAP_GROWSDOWN,...) и передать его в clone.

Murr ★★
()
Ответ на: комментарий от Murr

>можно сделать void* stack = mmap(...MAP_ANONYMOUS|MAP_GROWSDOWN,...) и передать его в clone.

а ещё некоторые делают void* stack = malloc() и такое тоже работает(возможно не всегда)

cvv ★★★★★
()
Ответ на: комментарий от Murr

Thanks всем ответившим.

Я, к стыду своему, вообще не знаю, как ядро со стэком обходится. Когда вообще стэк расширяется?

А сама проблема такова:

На пустом месте на _некоторых_ машинах валится задача. Иногда -- просто выдает неверные ответы. По симптомам похоже на переполнение стэка. При этом:

1. Только на трех машинах ( из двух десятков). На других такого нет. Даже более более того, на группе из 4 АБСОЛЮТНО одинаковых машин задача систематически валяет ваньку -- на всех, кроме одной, на которой все ok. То есть, машины покупались одновременно, абсолютно одинаковые и с одинаковым Линухом.

2. "Ванька" абсолютно неповторима и появляется после 3-4 дней работы и десятков гигабайт переписанного дискового пространства.

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

4. чудеса происходили под аккаунтом, где ulimit -s (soft) не unlimited, а 8M.

Программа скомпилена gcc с единственным флагом -O2 (ну, еще не относящиеся к делу типа -D_FILE_OFFSET_BITS=64) Но тот же эффект наблюдался и для icc-скомпиленной программы.

Сейчас запустили эту задачку под ulimit -s unlimited, но ответ будем знать только через несколько дней.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

>Сейчас запустили эту задачку под ulimit -s unlimited, но ответ будем знать только через несколько дней.

А почему не под ulimit -SHs unlimited ???

cvv ★★★★★
()
Ответ на: комментарий от cvv

cvv :

> А почему не под ulimit -SHs unlimited ???

Для краткости ;)

ВСЕ unlimited

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

> вообще не знаю, как ядро со стэком обходится. Когда вообще стэк
> расширяется?

Murr все правильно написал про VM_GROWSUP.
все просто, если выходим за пределы стэка происходит page fault,
он проверяет RLIMIT_STACK, если не превысили - получаем новую
страничку, иначе SIGSEGV.

> на _некоторых_ машинах валится задача.

смотрите core, чего гадать?

> Иногда -- просто выдает неверные ответы. По симптомам похоже на
> переполнение стэка. При этом:

при переполнении стэка будет SIGSEGV, вряд ли могут быть
неверные ответы. разве что на SIGSEGV сидит хитрый обработчик,
который правит sigframe или longjump() делает.

idle ★★★★★
()
Ответ на: комментарий от idle

> если не превысили - получаем новую страничку

разумеется, есть ситуации, когда стэк не может быть
расширен, даже если rlimit не превышен, и свободная
память есть. например, кто-то всунул vma (mmap(MAP_FIXED))
в область расширения стэка. или ядро не смогло найти
другого места во время malloc/mmap если очень много
адресного пространства задача просила.

idle ★★★★★
()
Ответ на: комментарий от idle

2idle :

Thanks.

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

> смотрите core, чего гадать?

Она не генерилась (запрещено было лимитами). Да и валятся задачи редко, обычно просто неверный результат дают, так что поймать момент не так просто, потребуется несколько месяцев задачу гонять.

А нельзя ли как-нибудь устроить контроль переполнения стэка (типа, перед вызовом каждой функции запрещать доступ к текущему стэку, а сразу после возврата опять разрешать)? Помнится, в Борланде нечто такое было...

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

> А нельзя ли как-нибудь устроить контроль переполнения стэка

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

лучше повесьте обработчик на SIGSEGV, пусть он скажет, что случилось.
только, если действительно проблемы со стэком, не забудьте про
sigaltstack().

поскольку у вас процесс уже крутится, вы сейчас сделайте типа:
# gdb programm `pidof programm` и скажите 'r', и пусть работает.
если он таки упадет, вы увидите где.

idle ★★★★★
()
Ответ на: комментарий от idle

2idle:

> лучше повесьте обработчик на SIGSEGV

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

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

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

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

anonymous
()
Ответ на: комментарий от anonymous

anonymous (*) (20.10.2004 23:49:25):

> ...подобное может возникать при частичном затирании стэка

Вот, я об этом и подумал.

> возможно просто изменение размера предела в юлимите и соответственно разный размер начального стэка сказывается на том что при большем стэке твое переполнение на залазит на уже используемую область а когда стэк меньше всеже залазит :)

Это я и хотел проверить.

Но после объяснений idle понял, что это невозможно.

Кстати, сегодня задача досчиталась ( с unlimited стэком) -- то же самое, ошибка.

> в общем у тебя 100% гдето переполнение

Мистика состоит в том, что это проявляется только на нескольких конкретных машинах. На других, в т.ч. и ТОЧНО таких же (вплоть до железячных адресов) все работает правильно.

Die-Hard ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.