奇怪的 printk 对 linux 堆栈大小测试的影响
Strange printk effect on linux stack size testing
I am trying to test linux kernel stack size in 64 bit.
我发现了这种奇怪的行为。
我写了下面的代码来使内核崩溃,但奇怪的是
只有当 printk 被取消注释时它才会崩溃,
否则运行正常,没有 errors/warnings!!
#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 modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-53-generic'
CC [M] /home/naveenvc/work/ker/crash_stack/crash_stack.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/naveenvc/work/ker/crash_stack/crash_stack.mod.o
LD [M] /home/naveenvc/work/ker/crash_stack/crash_stack.ko
make[1]: Leaving directory '/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 modules make[1]: Entering
directory '/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: In function
‘crash_stack_init’:
/home/naveenvc/work/ker/crash_stack/crash_stack.c:14:1: warning: the
frame size of 8200 bytes is larger than 1024 bytes
[-Wframe-larger-than=] } ^
Building modules, stage 2. MODPOST 1
modules CC
/home/naveenvc/work/ker/crash_stack/crash_stack.mod.o LD [M]
/home/naveenvc/work/ker/crash_stack/crash_stack.ko make[1]: Leaving
directory '/usr/src/linux-headers-4.4.0-53-generic'
可能是什么原因造成的?
堆栈大小有详细记录,以上不是正确的测试方法,特别是在使用大页面支持堆栈的旧内核中,上述代码会跳转到下一个堆栈。
注释掉 prink 的 func __crash_stack_init 是叶函数 - 它不调用任何东西,因此编译器确切地知道局部变量会发生什么。特别是在这段代码中,它发现不需要完整的数组,因此它没有被分配。但是,对 printk 的调用传递了 arr。编译器不知道 func 将如何处理它,因此它必须在堆栈上保留 1024 * sizeof(long),这会导致警告。
堆栈在几年前达到了 16KB,您可以从这里开始阅读 https://lwn.net/Articles/600644/
I am trying to test linux kernel stack size in 64 bit.
我发现了这种奇怪的行为。 我写了下面的代码来使内核崩溃,但奇怪的是 只有当 printk 被取消注释时它才会崩溃, 否则运行正常,没有 errors/warnings!!
#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 modules make[1]: Entering directory '/usr/src/linux-headers-4.4.0-53-generic' CC [M] /home/naveenvc/work/ker/crash_stack/crash_stack.o Building modules, stage 2. MODPOST 1 modules CC /home/naveenvc/work/ker/crash_stack/crash_stack.mod.o LD [M] /home/naveenvc/work/ker/crash_stack/crash_stack.ko make[1]: Leaving directory '/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 modules make[1]: Entering directory '/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: In function ‘crash_stack_init’: /home/naveenvc/work/ker/crash_stack/crash_stack.c:14:1: warning: the frame size of 8200 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^
Building modules, stage 2. MODPOST 1 modules CC
/home/naveenvc/work/ker/crash_stack/crash_stack.mod.o LD [M] /home/naveenvc/work/ker/crash_stack/crash_stack.ko make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-53-generic'
可能是什么原因造成的?
堆栈大小有详细记录,以上不是正确的测试方法,特别是在使用大页面支持堆栈的旧内核中,上述代码会跳转到下一个堆栈。
注释掉 prink 的 func __crash_stack_init 是叶函数 - 它不调用任何东西,因此编译器确切地知道局部变量会发生什么。特别是在这段代码中,它发现不需要完整的数组,因此它没有被分配。但是,对 printk 的调用传递了 arr。编译器不知道 func 将如何处理它,因此它必须在堆栈上保留 1024 * sizeof(long),这会导致警告。
堆栈在几年前达到了 16KB,您可以从这里开始阅读 https://lwn.net/Articles/600644/