- 🐚作者简介:花神庙码农(专注于Linux、WLAN、TCP/IP、Python等技术方向)
- 🐳博客主页:花神庙码农 ,地址:https://blog.csdn.net/qxhgd
- 🌐系列专栏:Linux技术
- 📰如觉得博主文章写的不错或对你有所帮助的话,还望大家三连支持一下呀!!! 👉关注✨、点赞👍、收藏📂、评论。
- 如需转载请参考转载须知!!
Linux内核及用户态程序异常问题的查证方法
- 编译配置
- 对于内核
- 对于用户态程序
- -g选项
- strip
- 工具
- 收集信息
- 问题定位
- gdb
- 通过l命令列出源码
- 可通过b命令设置断点
- addr2line
- 常用选项
- 使用实例
- objdump
- 常用选项
- 使用实例
编译配置
对于内核
- 建议开启下面的编译宏:
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
- 编译建议增加-g选项。
对于用户态程序
-g选项
- 默认编译生成的可执行文件是无法使用 gdb 来跟踪或调试的,需要在makefile或gcc命令中增加-g选项;
- 加上-g选项以后,gcc在编译是会做以下额外的操作:
– 创建符号表,符号表包含了程序中使用的变量名称的列表。
– 关闭所有的优化机制,以便程序执行过程中严格按照原来的C代码进行。
strip
- 该命令会从特定文件中剥掉一些符号信息和调试信息。因此,虽然编译的时候加了-g选项,但是该命令会让将-g的操作消失,这点务必注意。
工具
- 工具链(objdump、addr2line等)
- gdb
收集信息
- oops导栈信息
- oops的vmlinux或.o文件
- 故障版本的编译目录
问题定位
gdb
通过l命令列出源码
gdb oops.ko or gdb oops.o
l*(my_oops_init+0x15)
- 命令格式:
l*(函数名+偏移地址)或者(函数入口地址+偏移地址)
可通过b命令设置断点
- 对于内核而言,如oops时,pc指向0x8024b898,则通过下面方式设置断点:
# gdb vmlinux# (gdb) b*0x8024b898
之后,可定位故障处理内核的哪个文件哪一行。
addr2line
常用选项
- -a --addresses Show addresses
- -e --exe= Set the input file name (default is a.out)
使用实例
- 内核实例:
addr2line -e vmlinux -a ffffffff8124d222
- 应用程序实例:
addr2line -e myapp 080483c9
objdump
常用选项
- -d, --disassemble Display assembler contents of executable sections (仅反汇编执行段)
- -D, --disassemble-all Display assembler contents of all sections(反汇编所有段)
- -S, --source Intermix source code with disassembly(尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数)
- l,–line 有的objdump版本支持该参数,可以先试试代码执行地址和对应行数
使用实例
- 对某个so进行反汇编:
objdump -S xxx.so > xxx.txt
objdump -S -D xxx.so > xxx.txt
- 如果编译时没有-g选项,则反汇编的结果没有C源码,分析纯汇编有点难度的。
如本文对你有些许帮助,欢迎大佬支持我一下,您的支持是我持续创作的不竭动力
支持我的方式