使用gdb调试内核错误信息

转载 2016年05月31日 14:34:33

配置gdb:

Kernel hacking  --->
    [*] Kernel debugging
    [*] Compile the kernel with debug info


内核开发时有时候出现Oops,例如一个野指针会导致内核崩溃,如运行时出现以下log:现在有三种方法可以找出具体出现野指针的地方

[plain] view plain copy
 print?
  1.    5.438972] bells bells:  wm5102-aif1 <-> samsung-i2s.0 mapping ok  
  2. [    5.443812] bells bells: Failed to add route OPCLK->Sub CLK_SYS  
  3. [    5.450499] Unable to handle kernel NULL pointer dereference at virtual address 00000010  
  4. [    5.457770] pgd = c0004000  
  5. [    5.460504] [00000010] *pgd=00000000  
  6. [    5.463959] Internal error: Oops: 5 [#1] PREEMPT SMP ARM  
  7. [    5.469249] CPU: 3    Not tainted  (3.4.5-g092c4c5 #75)  
  8. [    5.474457] <span style="color:#990000;">PC is at snd_soc_dai_set_sysclk+0x10/0x84</span>  
  9. [    5.479481] LR is at bells_late_probe+0x60/0x198  
  10. [    5.484133]<span style="color:#FFCC33;"> pc : [<c040faa0>]</span>    lr : [<c0424030>]    psr: 60000013  
  11. [    5.484139] sp : d683bd58  ip : d683bd80  fp : d683bd7c  
  12. [    5.495579] r10: 00000000  r9 : c08a41f8  r8 : 00000000  
  13. [    5.500723] r7 : d62bf400  r6 : 00000000  r5 : d69ab800  r4 : 00000000  
  14. [    5.507284] r3 : 00000000  r2 : 00000000  r1 : 00000002  r0 : 00000000  
  15. [    5.513731] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel  
  16. [    5.521074] Control: 10c5387d  Table: 4000406a  DAC: 00000015  
  17. [    5.526799]   
  18. [    5.526802] PC: 0xc040fa20:  

0 直接通过addr2line命令获取,例如:

$ arm-none-linux-gnueabi-addr2line -e vmlinux c040faa0 

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

addr2line 代码如下

[plain] view plain copy
 print?
  1. #!/bin/bash  
  2. #  
  3. # addr2line.sh -- Convert PC address to source code line, open the file and point to the line  
  4. #  
  5.   
  6. ADDR=$1  
  7. [ -z "$ADDR" ] && echo -e "Usage: Please specify the PC address\n    $0 PC_ADDR" && exit 1  
  8. [ -z "$CROSS_COMPILE" ] && CROSS_COMPILE=arm-none-linux-gnueabi-  
  9.   
  10. ADDR2LINE=${CROSS_COMPILE}addr2line  
  11. file_line=`$ADDR2LINE -e vmlinux $ADDR`  
  12. if [ "$file_line" == "??:0" ]; then  
  13.     echo "ERROR: Can not find the line for $ADDR"  
  14.     exit 2  
  15. else  
  16.     vim -c "set number" -c "set fdm=manual" $(echo $file_line | sed -e "s/:/ +/g")  
  17. fi  

1 通过gdb定位

1.1 首先运行gdb,不过需要使用出错内核的vmlinux 
执行 $ 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_sysclk
c04116bc 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的位置即可


转自:http://blog.csdn.net/hellowxwworld/article/details/10731653

Linux内核之GDB基本调试方法

一般单板软件Linux内核出现crash如何采用GDB工具进行调试? 基本方法过程如下: 1. 为了测试GDB操作,故意在kernel/linux/fs/ioctl.c文件的do_vfs_ioct...
  • wuruixn
  • wuruixn
  • 2014年07月31日 17:23
  • 7984

如何在安卓系统上使用arm-linux-gdb调试内核

现在很多安卓平台都没有把gdb调试工具编译进去,因此需要我们自己安装交叉编译环境下的gdb工具。 具体实现只需几步即可: 1. 下载最新的arm-linux-gdb源码包     下载地址:http:...
  • wlwl0071986
  • wlwl0071986
  • 2016年03月15日 15:04
  • 1596

GDB调试内核总结

这里记录平时使用gdb调试内核KE的步骤和方法. 有不足的地方也请大家指出和完善. 1 必备工具和文件  Gdb,addr2line,vmlinux以及内核coredump文件 在64位平台,g...
  • bin_linux96
  • bin_linux96
  • 2015年11月09日 11:20
  • 1705

gdb调试内核(整理)

1、断点   1) 设置断点    break +offset    break -offset                      (在当前行号的前面或后面的offset行停住。)   ...
  • luckywang1103
  • luckywang1103
  • 2014年12月27日 15:33
  • 867

使用bochs和gdb联合调试Linux内核

bochs这个软件准确来说应该叫做“模拟器”,而不是虚拟机,因为VMware等虚拟机是将Guest系统所有的指令都放到真实硬件上执行,而bochs模拟器则是直接用软件模拟硬件的执行,举个例子,在boc...
  • u010035971
  • u010035971
  • 2016年03月15日 17:37
  • 934

使用gdb跟踪Linux内核启动过程

start_kernel()是内核的汇编与C语言的交接点,在该函数以前,内核的代码都是用汇编写的,完成一些最基本的初始化与环境设置工作。start_kernel就像是c代码中的main函数。不管你关注...
  • sunyeyi
  • sunyeyi
  • 2015年03月21日 18:17
  • 2785

使用Qemu+gdb来调试内核

昨天听别人讲使用Qemu和gdb来实现源码级内核调试,今天试了一下,果然非常方便,现简单的记录一下。Qemu是一个开源的虚拟机软件,能够提供全系统的仿真,可以运行在多个平台上,并仿真多个别的平台。Qe...
  • iamljj
  • iamljj
  • 2010年06月08日 11:29
  • 17615

QEMU+GDB调试方法

两年前调试usb/ip开源项目时,就曾用虚拟机远程调试过Windows和Linux系统内核,当时在VMware Workstation上创建两个虚拟机进行调试,也没有记录下如何配置调试,只是大体的还记...
  • flyforfreedom2008
  • flyforfreedom2008
  • 2015年04月16日 21:42
  • 1974

linux内核调试环境搭建步骤

linux内核调试环境搭建步骤 linux 2.6.26 与其后的版本,其内置已经支持kgdb了。 下面的内容描述了怎样在Linux环境下,搭建虚拟机调试linux内核的主要步骤:...
  • bamboolsu
  • bamboolsu
  • 2015年01月23日 17:38
  • 1810

GDB简单调试linux内核与模块的方法

gdb 对于看系统内部是非常有用. 在这个级别精通调试器的使用要求对 gdb 命令有信心, 需要理解目标平台的汇编代码,  以及对应源码和优化的汇编码的能力.      调试器必须把内核作为一...
  • wh8_2011
  • wh8_2011
  • 2016年07月28日 07:16
  • 1703
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用gdb调试内核错误信息
举报原因:
原因补充:

(最多只允许输入30个字)