在Linux内核中提供了一个可以打印出内核调用堆栈的函数 dump_stack()

该函数在我们调试内核的过程中可以打印出函数调用关系,该函数可以帮助我们进行内核调试,以及让我们了解内核的调用关系。

该函数头文件为:

#include <asm/ptrace.h>

使用方式:

直接在想要查看的函数中添加

dump_stack();

案例:

随便写了一个模块test.c,test.c代码如下:

    #include <linux/module.h>   
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <asm/ptrace.h>
     
    void aaa(int a);
    void bbb(int b);
    void ccc(int c);
     
    void aaa(int a)
    {
        int b = a + 10;
        bbb(b);
    }
     
    void bbb(int b)
    {
        int c = b + 10;
        ccc©;
    }
     
    void ccc(int c)
    {
        dump_stack();
        printk(“c is %d\n”,c);
    }
     
    static int __init my_init( void )
    {
        int a = 10;
        aaa(a);
        printk(“my_init \n”);  
    }
     
    static void __exit my_exit(void )
    {
            printk(“my_exit \n”);    
    }
     
    module_init(my_init);
    module_exit(my_exit);
    MODULE_LICENSE(“GPL”);

Makefile

    ifneq   (KaTeX parse error: Expected 'EOF', got '&' at position 23: …RELEASE),)<br> &̲nbsp;&nbsp;&nbs…(shell uname -r)/build
    PWD     := KaTeX parse error: Expected 'EOF', got '&' at position 17: …shell pwd)<br> &̲nbsp;&nbsp;&nbs…(MAKE) -C ( K D I R ) S U B D I R S = (KDIR) SUBDIRS= (KDIR)SUBDIRS=(PWD) modules
        rm -r -f .tmp_versions .mod.c ..cmd *.o *.symvers
     
    endif

make编译完成后,使用insmod插入模块,使用dmesg打印调用信息,得到信息如下:

    [ 1311.888605] Call Trace:
    [ 1311.888612]  [<ffffffffa001a000>] ? 0xffffffffa0019fff
    [ 1311.888616]  [<ffffffff816cd58e>] dump_stack+0x19/0x1b
    [ 1311.888619]  [<ffffffffa038c015>] ccc+0x15/0x30 [test]
    [ 1311.888621]  [<ffffffffa038c041>] bbb+0x11/0x20 [test]
    [ 1311.888623]  [<ffffffffa038c061>] aaa+0x11/0x14 [test]
    [ 1311.888625]  [<ffffffffa001a00e>] my_init+0xe/0x1000 [test]
    [ 1311.888628]  [<ffffffff81002122>] do_one_initcall+0xf2/0x1a0
    [ 1311.888632]  [<ffffffff810c3ef3>] load_module+0x1403/0x1c00
    [ 1311.888637]  [<ffffffff8134fab0>] ? ddebug_add_module+0xf0/0xf0
    [ 1311.888639]  [<ffffffff810c47d1>] SyS_init_module+0xe1/0x130
    [ 1311.888643]  [<ffffffff816dc86f>] tracesys+0xe1/0xe6
    [ 1311.888645] c is 30
    [ 1311.888645] my_init

可以看到在函数ccc中使用dump_stack()打印出了ccc的函数调用栈。

在内核开发中,我们可以使用dump_stack()来打印相关信息,同时在内核源码学习中也可以用来了解函数调用关系。
 
原文链接:https://blog.csdn.net/SweeNeil/article/details/88061381

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐