clinuxlinux-kernelprintk

Strange printk effect on linux stack size testing


I am trying to test linux kernel stack size in 64 bit. 

I found this weird behaviour. I wrote following code to crash the kernel but strange thing is that it crashes only if printk is uncommented, otherwise runs fine with no 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'

What could be causing this?


Solution

  • The stack size is well documented and the above is not the right way to test, in particular in older kernels which used hugepages to back the stack the aforementioned code would jump over to the next stack.

    The func __crash_stack_init with prink commented out is a leaf function - it does not call anything, so the compiler knows exactly what happens with local vars. In particular in this code it sees the full array is not needed and thus its not being allocated. However, the call to printk passes arr in. The compiler does not know what the func is going to do with it, thus it has to reserve 1024 * sizeof(long) on the stack which results in the warning.

    Stacks got bumped to 16KB years ago, you can start reading here https://lwn.net/Articles/600644/