开发者为了能够更方便调试内核问题,在内核镜像中加入了一个运行时可访问的符号表,并提供了对这个符号表的访问和查询接口,这就是kallsyms。
kallsyms使用一个私有数据块来保存符号信息,在编译时被链接到了内核里,以只读全局变量的形式存在。kallsyms提供了访问和查询这个符号表全局变量的接口。这个符号表不是vmlinux中elf的符号表。
在Kernel oops中,会显示stack backtrace,其中显示的符号信息,就是利用kallsyms实现的。
- /include/linux/kallsyms.h
- /kernel/kallsyms.c
- /kernel/module/kallsyms.c
printk
printk中可以通过%px显示指针地址,通过%ps或%pS(包含offset/size信息)显示指针对应的符号。
print_ip_sym
printk的封装,便捷打印addr对应符号位置。
kallsyms_lookup
lookup_symbol_name
通过addr查找symbol,包括在symbol的size和symbol内的偏移
kallsyms_lookup_name
查找symbol对应的地址
dump_stack
打印当前调用栈
使能kallsyms符号表
CONFIG_KALLSYMS=y,CONFIG_KALLSYMS_ALL=y
查看kallsyms符号表
cat /proc/kallsyms
* 使用root权限查看
dump stack提供了stack backtrace相关接口,详见 dump_stack.c
stacktrace.c
可以通过 dump_stack
打印当前调用栈,通过 arch_stack_walk
对stack进行遍历,通过传入 task_struct
打印线程栈。