根据内核Oops 定位代码工具使用— addr2line 、gdb、objdump
来源:互联网 发布:南京java培训评论 编辑:程序博客网 时间:2024/05/16 14:18
(这三种工具都在out/host/linux-x86目录下)
内核开发时有时候出现Oops,例如一个野指针会导致内核崩溃,如运行时出现以下log:现在有三种方法可以找出具体出现野指针的地方
- 5.438972] bells bells: wm5102-aif1 <-> samsung-i2s.0 mapping ok
- [ 5.443812] bells bells: Failed to add route OPCLK->Sub CLK_SYS
- [ 5.450499] Unable to handle kernel NULL pointer dereference at virtual address 00000010
- [ 5.457770] pgd = c0004000
- [ 5.460504] [00000010] *pgd=00000000
- [ 5.463959] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
- [ 5.469249] CPU: 3 Not tainted (3.4.5-g092c4c5 #75)
- [ 5.474457] PC is at snd_soc_dai_set_sysclk+0x10/0x84</span>
- [ 5.479481] LR is at bells_late_probe+0x60/0x198
- [ 5.484133]<span style="color:#FFCC33;"> pc : [<c040faa0>]</span> lr : [<c0424030>] psr: 60000013
- [ 5.484139] sp : d683bd58 ip : d683bd80 fp : d683bd7c
- [ 5.495579] r10: 00000000 r9 : c08a41f8 r8 : 00000000
- [ 5.500723] r7 : d62bf400 r6 : 00000000 r5 : d69ab800 r4 : 00000000
- [ 5.507284] r3 : 00000000 r2 : 00000000 r1 : 00000002 r0 : 00000000
- [ 5.513731] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
- [ 5.521074] Control: 10c5387d Table: 4000406a DAC: 00000015
- [ 5.526799]
- [ 5.526802] PC: 0xc040fa20:
0 直接通过addr2line命令获取,例如:
$ arm-none-linux-gnueabi-addr2line -e vmlinux c040faa0 //跟上出错时pc指针位置
注:请确保CROSS_COMPILE跟你编译用的是一样的前缀,例如上面的arm-none-Linux-gnueabi-,你编译时也必须是这个,不然算出来的行号可能会偏差比较大。
addr2line 代码如下
- #!/bin/bash
- #
- # addr2line.sh -- Convert PC address to source code line, open the file and point to the line
- #
- ADDR=$1
- [ -z "$ADDR" ] && echo -e "Usage: Please specify the PC address\n $0 PC_ADDR" && exit 1
- [ -z "$CROSS_COMPILE" ] && CROSS_COMPILE=arm-none-linux-gnueabi-
- ADDR2LINE=${CROSS_COMPILE}addr2line
- file_line=`$ADDR2LINE -e vmlinux $ADDR`
- if [ "$file_line" == "??:0" ]; then
- echo "ERROR: Can not find the line for $ADDR"
- exit 2
- else
- vim -c "set number" -c "set fdm=manual" $(echo $file_line | sed -e "s/:/ +/g")
- fi
1 通过gdb定位
1.1 首先运行gdb,不过需要使用出错内核的vmlinux
执行
1.2 设置断点,即上面log信息中的用黄色重点标记的pc地址
$ arm-linux-gnueabi-gdb vmlinux
1.2 设置断点,即上面log信息中的用黄色重点标记的pc地址
执行 (gdb) b*0xc040faa0
Breakpoint 1 at 0xc040faa0: file sound/soc/soc-core.c, line 1070.
此时,我们知道了在 sound/soc/soc-core.c文件的1070行出错,这下我们就锁定了范围,具体解决了;
1.3 如果你不想再另打开一个窗口去看该函数,也可以直接在当前窗口查看该函数
(gdb) set listsize 50(设置显示50行的内容)
(gdb) list *0xc040faa0(查看显示的内容)
2 根据查询内核符号表和反汇编信息定位,它可以不依赖出错内核的vmlinux
2.1 根据上面红色标记的log信息,PC is at snd_soc_dai_set_sysclk+0x10/0x84
0x10:表示出错的偏移位置,0x84表示snd_soc_dai_set_sysclk函数的大小
2.2 现在就是找到snd_soc_dai_set_sysclk函数的位置,
$ arm-linux-gnueabi-nm vmlinux | grep snd_soc_dai_set_sysclkc04116bc T snd_soc_dai_set_sysclk
$ arm-linux-gnueabi-objdump -S vmlinux –start-address=0xc04116bc –stop-address=0xc04116bc > ~/temp/soc
2.3 接下来就去查看vim ~/temp/soc文件, 找到0xc04116bc+0x10的位置即可
0 0
- 根据内核Oops 定位代码工具使用— addr2line 、gdb、objdump
- linux内核panic/oops/crash分析(addr2line,objdump,gdb)
- 根据内核Oops 定位代码
- 根据内核Oops 定位代码
- 根据内核Oops 定位代码
- 根据内核Oops 定位代码
- 根据内核Oops 定位代码
- 根据内核Oops 定位代码
- 根据内核Oops 定位代码
- 用 addr2line 定位 OOPS 死机代码位置
- 使用Addr2line工具定位死机代码
- linux内核调试工具 oops ksymoops objdump
- addr2line/objdump/nm/readelf使用
- android addr2line + objdump定位crash 问题
- objdump和addr2line 使用的例子
- 定位oops代码
- objdump & nm & addr2line
- addr2line objdump命令使用方法
- 双向解耦TCP协议开发(一)
- Java之美[从菜鸟到高手演变]之字符串
- linux进程创造 - 内核进程初始化及创建
- poj3261 Milk Patterns
- java中excel表格批量导入
- 根据内核Oops 定位代码工具使用— addr2line 、gdb、objdump
- 【c#】C#中的哈希表(HashTable)详解
- 通过多线程模拟实现Master-Worker模式
- Python爬虫之自动登录与验证码识别
- __attribute__编译属性---section
- 沉浸式状态栏实现
- 利用UITableViewController做静态单元格(代码实现)
- exit()和_exit()区别
- 5 Tips for Instant Interview Success