Linux打印内核函数调用栈(dump_stack)

本文介绍了Linux内核中用于调试的dump_stack()函数,该函数能打印出内核调用堆栈,帮助开发者理解函数调用关系。通过示例代码展示了如何在模块中使用dump_stack(),并在加载模块后,通过dmesg命令观察到函数调用轨迹,从而辅助内核开发和学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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 (KDIR)SUBDIRS=(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.youkuaiyun.com/SweeNeil/article/details/88061381

<think>嗯,用户问的是在函数中加入dump_stack()为什么没有打印。首先,我得回想一下dump_stack()这个函数的作用。dump_stack()Linux内核中的一个函数,用来打印当前的调用堆信息,通常在内核开发或者调试驱动时使用。如果用户是在用户空间的C程序中使用这个函数,那肯定无法编译通过,因为用户空间的程序无法直接调用内核函数。 然后,可能的另一个情况是用户可能混淆了内核空间和用户空间的调试方法。在用户空间,打印通常需要使用backtrace()系列函数,比如glibc提供的backtrace和backtrace_symbols。需要检查用户是否在正确的环境下使用对应的函数。 接下来,考虑用户是否在内核模块中正确使用了dump_stack()。即使在内核模块中,也需要确认是否包含了正确的头文件,比如linux/kernel.h,以及编译选项是否正确,比如是否有启用调试配置。另外,内核日志缓冲区可能需要通过dmesg命令查看,用户可能没有使用dmesg来查看输出,导致看不到打印信息。 还有权限问题,可能需要root权限才能查看内核日志。或者内核配置中没有启用相关的调试选项,比如CONFIG_DEBUG_KERNEL,这会导致dump_stack()不输出信息。此外,检查是否有printk的日志级别设置过低,导致信息被过滤掉。 总结可能的原因:用户可能在用户空间错误使用内核函数;在内核模块中未正确配置或查看日志的方式不对;缺少必要的头文件或编译选项;日志级别问题或权限问题。 然后需要给出解决方法:确认使用环境,用户空间使用backtrace,内核模块确保正确使用并查看dmesg。提供示例代码,区分用户空间和内核空间的正确用法。最后提醒检查配置和权限。 相关问题需要围绕内核与用户空间调试、堆打印函数、内核模块编译和日志查看等方面提出。</think><< 在C语言中`dump_stack()`无打印的常见原因及解决方法: 1. **用户空间程序错误使用内核函数**: - `dump_stack()`是Linux内核专用函数,用户空间程序无法直接调用 - 解决方法:使用glibc的`backtrace`函数族 ```c #include <execinfo.h> void print_stack(void) { void *buffer[100]; int n = backtrace(buffer, 100); char **symbols = backtrace_symbols(buffer, n); for (int i = 0; i < n; i++) printf("%s\n", symbols[i]); free(symbols); } ``` 2. **内核模块未正确配置**: - 需要确保内核模块编译时包含正确头文件 ```c #include <linux/kernel.h> // 必须包含的头文件 #include <linux/module.h> ``` 3. **未查看内核日志缓冲区**: - `dump_stack()`输出到内核环形缓冲区,需用`dmesg`命令查看 ```bash dmesg | tail -n 20 ``` 4. **内核配置问题**: - 确保内核配置开启调试选项: ```makefile CONFIG_DEBUG_KERNEL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y ``` 5. **权限问题**: - 需要root权限查看内核日志 ```bash sudo dmesg ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值