一个oops问题的调试

参考文档

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:[] Not tainted
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:
[] vfs_write+0xb8/0x130
[] sys_write+0x42/0x70
[] syscall_call+0x7/0xb

注:示例是随便写的

 

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 ?


Code: e89dadf0 e1a0c00d e92dd800 e24cb004 (e1903f9f) 
//出错指令附近的指令机器码,比如(出错指令在小括号内)。



 __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

你可能感兴趣的:(kernel)