参考文档
kernel document里oops-trace.txt
LDD 第四章
打印信息中会告诉你死在哪个函数
然后去查找pc 寄存器指针位置(即下面的EIP)
Unable to handle kernel NULL pointer dereference at virtual address 00000000
printing eip:
d083a064
Oops: 0002 [#1]
SMP
CPU: 0
EIP: 0060:[
EFLAGS: 00010246 (2.6.6)
EIP is at faulty_write+0x4/0x10 [faulty]
eax: 00000000 ebx: 00000000 ecx: 00000000 edx: 00000000
esi: cf8b2460 edi: cf8b2480 ebp: 00000005 esp: c31c5f74
ds: 007b es: 007b ss: 0068
Process bash (pid: 2086, threadinfo=c31c4000 task=cfa0a6c0)
Stack: c0150558 cf8b2460 080e9408 00000005 cf8b2480 00000000 cf8b2460 cf8b2460
fffffff7 080e9408 c31c4000 c0150682 cf8b2460 080e9408 00000005 cf8b2480
00000000 00000001 00000005 c0103f8f 00000001 080e9408 00000005 00000005
Call Trace:
[
[
[
注:示例是随便写的
Oops: 0002 [#1]
其中0002代表错误码 (读错误、发生在内核空间),#1代表Oops发生次数。
* error_code:
* bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
首先arm-linux-objdump -d vmlinux > dump
查找指针所对应的指令
c0279f18: ea000032 b c0279fe8
c0279f1c: e288700c add r7, r8, #12
c0279f20: e1530007 cmp r3, r7
c0279f24: 31a07003 movcc r7, r3
c0279f28: e1a0300d mov r3, sp
c0279f2c: 35900018 ldrcc r0, [r0, #24]
c0279f30: e3c36d7f bic r6, r3, #8128 ; 0x1fc0
c0279f34: e3c6603f bic r6, r6, #63 ; 0x3f
c0279f38: 33800008 orrcc r0, r0, #8
c0279f3c: 35840018 strcc r0, [r4, #24]
c0279f40: e58d200c str r2, [sp, #12]
然后去找出错函数的文件
arm-linux-objdump -S sysfs.o > dump2
查找具体出错的位置
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
34: e59f307c ldr r3, [pc, #124] ; b8
38: e1530007 str r3, [r4, #56] ; 0x38
entry->prev = LIST_POISON2;
3c: e59f3078 ldr r3, [pc, #120] ; bc
40: e584303c str r3, [r4, #60] ; 0x3c
unsigned long tmp;
int result;
smp_mb();
其实前面的log中 sys_write+0x42/0x70 这种表示从sys_write函数开始往下0x42行
然后发现是一个指针问题
ktype的指针不对
但这个指针指向的是一个全局变量device_ktype
后来发现添加设备时 全局变量加了个__initdata 结果挂载系统是这个全局变量会被释放掉。
而出现这个问题是因为这段代码是我copy的, 看来还是要自己打字写代码,少copy。
这个问题还有个更简单点的办法
http://elinux.org/Main_Page
pc : [] lr : [ ] psr: a0000013
# arm-none-linux-gnueabi-addr2line -f -e vmlinux c01b063c msmfb_suspend /home/gnutoo/embedded/htcdream/SHR/kernel/linux/drivers/video/msm/msm_fb.c:485参数也可用这个-C -f -s -e
重新编译内核时,选上kernel hacking--->compile the kernel with debug info
---->kernel debugging ?
system_map中查到free_block地址0x40097ac0,+0x78得到0x40097B38
arm-gdb vmlinux
(gdb) l *0x40097B38
在命令行上键入命令:l(小写的L) * at cif_cam_isr_in8920+0x5c // l表示查找,*表示通配符
CONFIG_FRAME_POINTER ?
__do_kernel_fault(mm, addr, fsr, regs);
fsr 是CPSR
http://www.bsdmap.com/UNIX_html/ARM/apcsintro.html
http://www.360doc.com/content/11/1022/20/1317564_158274805.shtml