Странный эффект printk при тестировании размера стека linux
I am trying to test linux kernel stack size in 64 bit.
Я нашел это странное поведение. Я написал следующий код для сбоя ядра, но странным является то, что он падает, только если printk не закомментирован, в противном случае он работает без ошибок / предупреждений!!
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init crash_stack_init(void)
{
long arr[1024];
long *a;
a = &arr[0];
//printk("%p\n", &arr[0]);
return 0;
}
enter code here
static void __exit crash_stack_exit(void)
{
}
module_init(crash_stack_init);
module_exit(crash_stack_exit);
Here is the "make" output without the printk,
make -C /lib/modules/4.4.0-53-generic/build M=/home/naveenvc/work/ker/crash_stack модули make[1]: вход в каталог '/usr/src/linux-headers-4.4.0-53-generic' CC [M] /home/naveenvc/work/ker/crash_stack/crash_stack.o Сборка модулей, этап 2. Модули MODPOST 1 CC /home/naveenvc/work/ker/crash_stack/crash_stack.mod.o LD [M] /home/naveenvc/work/ker/crash_stack/crash_stack.ko make[1]: выход из каталога '/usr/src/linux-headers-4.4.0-53-generic'
And make output with printk,
make -C /lib/modules/4.4.0-53-generic/build M=/home/naveenvc/work/ker/crash_stack модули make[1]: вход в каталог '/usr/src/linux-headers-4.4.0-53-generic' CC [M] /home/naveenvc/work/ker/crash_stack/crash_stack.o > /home/naveenvc/work/ker/crash_stack/crash_stack.c: в функции' crash_stack_init ': /home/naveenvc/work/ker/crash_stack/crash_stack.c:14:1: предупреждение: размер кадра 8200 байт превышает 1024 байт [-Wframe-больше-than=] } ^
Сборка модулей, этап 2. МОДПОСТ 1, модули СС
/home/naveenvc/work/ker/crash_stack/crash_stack.mod.o LD [M] /home/naveenvc/work/ker/crash_stack/crash_stack.ko make[1]: выход из каталога '/ usr / src / linux-headers -4.4.0-53-родовое"
Что может быть причиной этого?
1 ответ
Размер стека хорошо задокументирован, и вышеприведенный вариант не является правильным способом тестирования, особенно в старых ядрах, которые использовали огромные страницы для поддержки стека, вышеупомянутый код перепрыгивал бы на следующий стек.
Func __crash_stack_init с закомментированным prink является листовой функцией - она ничего не вызывает, поэтому компилятор точно знает, что происходит с локальными переменными. В частности, в этом коде он видит, что полный массив не нужен и, следовательно, он не выделяется. Тем не менее, вызов printk передает arr. Компилятор не знает, что будет с ним делать func, поэтому он должен зарезервировать 1024 * sizeof(long) в стеке, что приведет к предупреждению.
Стеки были увеличены до 16 КБ лет назад, вы можете начать читать здесь https://lwn.net/Articles/600644/