linux内核dumpstack定位使用举例说明
- 游戏开发
- 2025-09-19 01:12:01

1,在 Linux 内核中,当你需要定位问题时,dump_stack() 函数是一个非常有用的工具,那么什么时候使用dump_stack,怎么使用dump_stack呢
通常使用的是前者)函数通常在以下情况下被用来帮助定位问题:
调试内核代码:当你在开发内核模块或内核代码时,遇到一个难以重现或理解的行为,你可以在代码中加入 dump_stack() 来查看当前的调用栈,帮助你理解代码执行流程。
处理内核错误:在内核代码中检测到错误或异常情况时,比如空指针解引用、越界访问等,可以在错误处理代码中调用 dump_stack() 来记录调用栈信息。
断言失败:使用 BUG()、BUG_ON() 或 WARN() 等宏来标记不应该发生的情况。如果这些断言失败,它们通常会调用 dump_stack() 来输出调用栈。
内核Oops:当内核发生一个Oops(Out-Of-Scope Page)错误时,内核会自动输出调用栈信息。这通常发生在非法内存访问或其他严重错误情况下。
2,举例使用
测试空指针,在一个函数里面添加空指针测试
static int problematic_function(void) { int *p = NULL; return *p; // 故意访问空指针,这将导致一个内核oops }
异常打印测试
if(problematic_function()) { printk(KERN_ERR "lark@test:rfkill_rk_set_power:blocked[%d]\n",blocked); dump_stack(); }
串口打印查看dump_stack打印情况
[ 3.842238] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 3.842925] SMP: stopping secondary CPUs [ 3.843276] CPU1: stopping [ 3.843278] CPU2: stopping [ 3.843285] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G D 5.10.160 #3 [ 3.843307] CPU3: stopping [ 3.844658] Hardware name: Rockchip RK3568 KICKPI K1B Board (DT) [ 3.845185] Call trace: [ 3.845413] dump_backtrace+0x0/0x1d0 [ 3.845738] show_stack+0x1c/0x24 [ 3.846041] dump_stack_lvl+0xcc/0xf0 [ 3.846365] dump_stack+0x14/0x30 [ 3.846666] local_cpu_stop+0x78/0x80 [ 3.846990] ipi_handler+0x160/0x270 [ 3.847315] handle_percpu_devid_fasteoi_ipi+0x94/0x16c [ 3.847776] __handle_domain_irq+0x78/0xe0 [ 3.848144] gic_handle_irq+0xf8/0x364 [ 3.848478] el1_irq+0xc8/0x180 [ 3.848759] cpuidle_enter_state+0xdc/0x40c [ 3.849128] cpuidle_enter+0x3c/0x50 [ 3.849453] do_idle+0x230/0x2e0 [ 3.849743] cpu_startup_entry+0x2c/0x60 [ 3.850089] secondary_start_kernel+0x184/0x1e0 [ 3.850493] CPU: 3 PID: 0 Comm: swapper/3 Tainted: G D 5.10.160 #3
查看代码可以看出空指针访问的异常。
我们这里只打印了堆栈,后面可以把PC指针和站指针一起打出来。
栈溢出测试
static int problematic_function(void) { int a[5]; return a[5]; }
if(problematic_function()) { printk(KERN_ERR "lark@test:rfkill_rk_set_power\n"); dump_stack(); }
查看dump_stack情况
[ 3.344597] lark@test:rfkill_wlan_probe [ 3.344605] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.160 #5 [ 3.344609] Hardware name: Rockchip RK3568 KICKPI K1B Board (DT) [ 3.344614] Call trace: [ 3.344625] dump_backtrace+0x0/0x1d0 [ 3.344631] show_stack+0x1c/0x24 [ 3.344637] dump_stack_lvl+0xcc/0xf0 [ 3.344642] dump_stack+0x14/0x30 [ 3.344649] rfkill_wlan_probe+0x6c/0x644 [ 3.344656] platform_drv_probe+0x58/0xac [ 3.344662] really_probe+0x10c/0x510 [ 3.344667] driver_probe_device+0x74/0x15c [ 3.344672] device_driver_attach+0xbc/0xcc [ 3.344677] __driver_attach+0x118/0x190 [ 3.344682] bus_for_each_dev+0x74/0xd0 [ 3.344687] driver_attach+0x28/0x30 [ 3.344692] bus_add_driver+0x124/0x240 [ 3.344696] driver_register+0x7c/0x124 [ 3.344701] __platform_driver_register+0x4c/0x54 [ 3.344707] rfkill_wlan_init+0x3c/0x44 [ 3.344711] rfkill_rk_init+0x2c/0x48 [ 3.344716] do_one_initcall+0x60/0x26c [ 3.344722] kernel_init_freeable+0x270/0x2e0 [ 3.344727] kernel_init+0x18/0x114 [ 3.344732] ret_from_fork+0x10/0x24
我们可以看出函数的调用栈信息。
int rockchip_wifi_power(int on) { struct rfkill_wlan_data *mrfkill = g_rfkill; struct rksdmmc_gpio *poweron, *reset; struct regulator *ldo = NULL; int bt_power = 0; bool toggle = false;
LOG("%s: %d\n", __func__, on);
if (!mrfkill) { LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__); return -1; } if(problematic_function()) { printk(KERN_ERR "lark@test:rfkill_rk_set_power:on[%d]\n",on); dump_stack(); }
.........忽略其它代码 }
linux内核dumpstack定位使用举例说明由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“linux内核dumpstack定位使用举例说明”
上一篇
模板字符串【ES6】