内核开发时有时候出现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 [ 5.479481] LR is at bells_late_probe+0x60/0x198 [ 5.484133] pc : [<c040faa0>] 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:
$ arm-none-linux-gnueabi-addr2line -e vmlinux c040faa0
注:请确保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