Размеры стека 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).

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