我们在调试内核时可以用printk打印信息。但有时我们不知道一个函数或者一个模块到底在哪里出了问题。这时我们可以用dump_stack打印信息,查看函数调用关系,找到问题的根源。使用实例:
hello.c
#include <linux/module.h> #include <linux/init.h> #include <linux/kprobes.h> #include <asm/traps.h> static int __init hello_init(void) { printk(KERN_ALERT "dump_stack start\n"); dump_stack(); printk(KERN_ALERT "dump_stack over\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_ALERT "test module\n"); } module_init(hello_init); module_exit(hello_exit);
Makefile
#hello_makefile obj-m :=hello.o KERNELDIR :=/lib/modules/$(shell uname -r)/build PWD :=$(shell pwd) all: make -C $(KERNELDIR) M=$(PWD) modules .PHONY :clean clean: rm -rf *.o *ko
然后make得到hello.ko
在运行insmod hello.ko把模块插入内核
运行dmesg
得到内核打印信息:
[384625.351387] Call Trace: [384625.387169] dump_stack+0x63/0x8b [384625.387181] ? 0xffffffffc03b8000 [384625.387184] hello_init+0x15/0x1000 [hello] [384625.389391] do_one_initcall+0x55/0x1a6 [384625.389399] ? 0xffffffffc03b8000 [384625.390037] do_init_module+0x5f/0x209 [384625.390048] load_module+0x1996/0x1da0 [384625.390052] SYSC_finit_module+0xe5/0x120 [384625.390054] ? SYSC_finit_module+0xe5/0x120 [384625.390056] SyS_finit_module+0xe/0x10 [384625.390116] entry_SYSCALL_64_fastpath+0x24/0xab [384625.390120] RIP: 0033:0x7f3054b5a4d9 [384625.390120] RSP: 002b:00007ffd4af6b128 EFLAGS: 00000206 ORIG_RAX: 0000000000000139 [384625.390175] RAX: ffffffffffffffda RBX: 00007f3054e1db20 RCX: 00007f3054b5a4d9 [384625.390176] RDX: 0000000000000000 RSI: 0000555dcee5326b RDI: 0000000000000003 [384625.390176] RBP: 0000000000001011 R08: 0000000000000000 R09: 00007f3054e1fea0 [384625.390177] R10: 0000000000000003 R11: 0000000000000206 R12: 00007f3054e1db78 [384625.390178] R13: 00007f3054e1db78 R14: 000000000000270f R15: 00007f3054e1e1a8 [384625.390570] dump_stack over
调用顺序:entry_SYSCALL_64_fastpath -> SyS_finit_module -> SYSC_finit_module -> load_module -> do_init_module -> do_one_initcall -> hello_init
更多信息参考:https://www.cnblogs.com/sky-heaven/p/6297675.html