博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Arm内核的Oops错误定位方法
阅读量:6239 次
发布时间:2019-06-22

本文共 2379 字,大约阅读时间需要 7 分钟。

出错的log信息如下:

1 Unable to handle kernel NULL pointer dereference at virtual address 00000014 2 pgd = c0004000 3 [00000014] *pgd=00000000 4 Internal error: Oops: 5 [#1] PREEMPT SMP ARM 5 Modules linked in: 6 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.45 #125 7 task: dc078000 ti: dc05a000 task.ti: dc05a000 8 PC is at at24c02_probe+0x78/0xa0 9 LR is at wake_up_klogd+0x84/0xac10 pc : [
] lr : [
] psr: 4000011311 sp : dc05bdb8 ip : dc05bcc0 fp : dc05bdd412 r10: c0a20a80 r9 : 0000009e r8 : c03e274813 r7 : 00000000 r6 : c08ccee4 r5 : c08ccf00 r4 : c075dbbc14 r3 : 00000000 r2 : 00000001 r1 : 20000193 r0 : 0000002015 Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel16 Control: 10c5387d Table: 1000404a DAC: 0000001517 Process swapper/0 (pid: 1, stack limit = 0xdc05a238)

1) 根据log信息,PC的值是 PC is at at24c02_probe+0x78/0xa0;

  at24c02_probe:表示出错的函数;

  0x78:表示出错语句在出错函数中的偏移位置;

  0xa0:表示at24c02_probe函数的大小;

2) 利用arm-none-linux-gnueabi-gcc-nm命令,找出函数at24c02_probe在内核中的线性地址(也可以从System.map文件中查找):

  arm-none-linux-gnueabi-gcc-nm vmlinux | grep at24c02_probe

  (vmlinux是没有压缩的镜像文件,在内核的编译文件夹中)

输出结果如下:

1 c03e2748 t at24c02_probe

说明at24c02_probe函数在内核中起始线性地址是0xc03e2748;

 

3) 根据偏差值0x78,利用arm-none-linux-gnueabi-objdump命令,显示出地址c03e2748-c03e27ff的反汇编(估算大概范围):

  arm-none-linux-gnueabi-objdump -S vmlinux --start-address=0xc03e2748 --stop-address=0xc03e27ff > /tmp/file

  偏差值+函数的起始地址=0x78+0xc03e2748=0xc03e27c0(也可以从log的pc值取得)

从file文件中找到的错误地方如下:

1  c03e27b8:       e59f0020        ldr     r0, [pc, #32]   ; c03e27e0 
2 56 c03e27bc: eb0c86de bl c070433c
3 57 printk("The i2c device id data is %d\n", id->driver_data);4 58 c03e27c0: e5971014 ldr r1, [r7, #20]5 59 c03e27c4: e59f0018 ldr r0, [pc, #24] ; c03e27e4
6 60 c03e27c8: eb0c86db bl c070433c

可以看出错误的语句是:printk("The i2c device id data is %d\n", id->driver_data);

 

另外一种方法: 

直接通过addr2line命令获取:

在编译的源码文件夹地下执行以下的命令,就可以显示出那一个函数哪一行代码出了问题, 

   arm-none-linux-gnueabi-addr2line -e vmlinux c03e27c0

/opt/Sourcery_CodeBench_for_ARM_Embedded/bin/arm-none-linux-gnueabi-addr2line -e vmlinux c03e27c0

注:请确保CROSS_COMPILE跟你编译用的是一样的前缀,例如上面的arm-none-linux-gnueabi-,你编译时也必须是这个,不然算出来的行号可能会偏差比较大。

 

 

 

(End)

转载于:https://www.cnblogs.com/yirenyang/p/4280986.html

你可能感兴趣的文章
day23-python操作数据库三
查看>>
第二次冲刺——第3天
查看>>
SpringMVC+Hibernate+Junit4+json基本框架近乎0配置
查看>>
Pro Android学习笔记(一三七):Home Screen Widgets(3):配置Activity
查看>>
Hadoop学习笔记(九)HDFS架构分析
查看>>
DB2数据库常用基本操作命令
查看>>
RHEL5.8安装Sybase 15.7_x86_64
查看>>
函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例
查看>>
武汉科技大学ACM :1002: A+B for Input-Output Practice (II)
查看>>
extjs中form.reset(true)出现的bug修复
查看>>
Some Android functions
查看>>
ORB-SLAM2学习4 initializer.h
查看>>
正向代理和反向代理
查看>>
1092 回文字符串(LCSL_DP)
查看>>
day01-Python介绍,安装,idea
查看>>
AX函数,将EXCEL列号转为列名
查看>>
UNDO -- Concept
查看>>
养生《一》
查看>>
es6的模块化--AMD/CMD/commonJS/ES6
查看>>
DevStack部署Openstack环境
查看>>