Размеры стека Linux
Я ищу хорошее описание стеков в ядре linux, но мне на удивление сложно найти что-нибудь полезное.
Я знаю, что для большинства систем стеки ограничены 4k, а для других - 8k. Я предполагаю, что каждый поток ядра/нижняя половина имеет свой собственный стек. Я также слышал, что если прерывание отключается, оно использует текущий стек потока, но я не могу найти никакой документации по этому поводу. Я ищу, как распределяются стеки, если для них есть хорошие процедуры отладки (я подозреваю, что переполнение стека для конкретной проблемы, и я хотел бы знать, возможно ли его скомпилировать ядро для полиции размеры стека и т.д.).
Ответы
Ответ 1
Причина, по которой документация недостаточна, состоит в том, что это область, довольно зависимая от архитектуры. Код действительно лучшая документация - например, макрос THREAD_SIZE
определяет (зависящий от архитектуры) размер стека ядра для каждого потока.
Стеки расположены в alloc_thread_stack_node()
. Указатель стека в struct task_struct
обновляется в dup_task_struct()
, который вызывается как часть клонирования потока.
Ядро проверяет переполнение стека ядра, помещая канарейку STACK_END_MAGIC
в конец стека. В обработчике ошибок страницы, если происходит ошибка в пространстве ядра, проверяется эта канарейка - см., Например, обработчик ошибок x86, который печатает сообщение Thread overran stack, or stack corrupted
после сообщения Oops, если канарейка стека была засорена.
Конечно, это не сработает во всех переполнениях стека, только в тех, которые заглушают канарейку стека. Тем не менее, вы всегда должны иметь возможность узнать из вывода Oops, если вы перенесли переполнение стека - это тот случай, если указатель стека находится ниже task->stack
.
Ответ 2
Размер стека процесса можно определить с помощью команды ulimit
. Я получаю 8192 KiB в своей системе:
$ ulimit -s
8192
Ответ 3
Для процессов вы можете контролировать размер стека процессов с помощью команды ulimit
(-s
). Для потоков размер стека по умолчанию сильно варьируется, но вы можете управлять им посредством вызова pthread_attr_setstacksize()
(при условии, что вы используете pthreads).
Что касается прерывания с использованием стека пользовательской среды, я несколько сомневаюсь в этом, поскольку доступ к пользовательской памяти - это своего рода проблема с ядром, особенно из процедуры прерывания. Но я точно не знаю.