WDS2期第30课2.1 符号表 驱动调试之段错误分析 结合内核打印信息PC值 确定地址范围是属于内核还是加载模块的空间System.map 查看内核或模块反汇编文件

大致流程如下:

  1. 结合内核打印信息PC值 ,
  2. 确定地址范围是属于内核还是加载模块的空间, vi System.map(内核源代码根目录下)确定内核的函数的地址范围; 把内核所有函数名及对应地址保存到文件cat /proc/kallsyms > 111.txt

System.map文件是编译内核时生成的,它记录了内核中的符号列表,以及符号在内存中的虚拟地址。
/proc/kallsyms文件是在内核启动后生成的,位于文件系统的/proc目录下,前提是内核必须打开CONFIG_KALLSYMS编译选项。它和System.map的区别是它同时包含了内核模块的符号列表。

在这里插入图片描述

  1. 查看内核或模块反汇编文件

需要详细栈回溯信息(栈里面函数的调用关系) 必须 在编译内核时 打开CONFIG_FRAME_POINTER
在这里插入图片描述

WDS笔记

二. 根据内核打印的段错误信息分析
a. 作为模块:

  1. 根据pc值确定该指令属于内核还是外加的模块
    pc=0xbf000018 它属于什么的地址?是内核还是通过insmod加载的驱动程序?
    先判断是否属于内核的地址: 看System.map确定内核的函数的地址范围:c0004000~c03265a4

如果不属于System.map里的范围,则它属于insmod加载的驱动程序

  1. 假设它是加载的驱动程序引入的错误,怎么确定是哪一个驱动程序?
    先看看加载的驱动程序的函数的地址范围
    cat /proc/kallsyms (内核函数、加载的函数的地址)
    从这些信息里找到一个相近的地址, 这个地址<=0xbf000018
    比如找到了:
    bf000000 t first_drv_open [first_drv]

  2. 找到了first_drv.ko
    在PC上反汇编它: arm-linux-objdump -D first_drv.ko > frist_drv.dis
    在dis文件里找到first_drv_open

    first_drv.dis文件里 insmod后
    00000000 <first_drv_open>: bf000000 t first_drv_open [first_drv]
    00000018 pc = bf000018

./firstdrvtest on
Unable to handle kernel paging request at virtual address 56000050
内核使用56000050来访问时发生了错误

pgd = c3eb0000
[56000050] *pgd=00000000
Internal error: Oops: 5 [#1]
Modules linked in: first_drv
CPU: 0 Not tainted (2.6.22.6 #1)
PC is at first_drv_open+0x18(该指令的偏移)/0x3c(该函数的总大小) [first_drv]
PC就是发生错误的指令的地址
大多时候,PC值只会给出一个地址,不到指示说是在哪个函数里

LR is at chrdev_open+0x14c/0x164
LR寄存器的值

pc = 0xbf000018

pc : [] lr : [] psr: a0000013
sp : c3c7be88 ip : c3c7be98 fp : c3c7be94
r10: 00000000 r9 : c3c7a000 r8 : c049abc0
r7 : 00000000 r6 : 00000000 r5 : c3e740c0 r4 : c06d41e0
r3 : bf000000 r2 : 56000050 r1 : bf000964 r0 : 00000000
执行这条导致错误的指令时各个寄存器的值

Flags: NzCv IRQs on FIQs on Mode SVC_32 Segment user
Control: c000717f Table: 33eb0000 DAC: 00000015
Process firstdrvtest (pid: 777, stack limit = 0xc3c7a258)
发生错误时当前进程的名称是firstdrvtest


Stack: (0xc3c7be88 to 0xc3c7c000)
be80: c3c7bebc c3c7be98 c008d888 bf000010 00000000 c049abc0
bea0: c3e740c0 c008d73c c0474e20 c3e766a8 c3c7bee4 c3c7bec0 c0089e48 c008d74c
bec0: c049abc0 c3c7bf04 00000003 ffffff9c c002c044 c3d10000 c3c7befc c3c7bee8
bee0: c0089f64 c0089d58 00000000 00000002 c3c7bf68 c3c7bf00 c0089fb8 c0089f40
bf00: c3c7bf04 c3e766a8 c0474e20 00000000 00000000 c3eb1000 00000101 00000001
bf20: 00000000 c3c7a000 c04a7468 c04a7460 ffffffe8 c3d10000 c3c7bf68 c3c7bf48
bf40: c008a16c c009fc70 00000003 00000000 c049abc0 00000002 bec1fee0 c3c7bf94
bf60: c3c7bf6c c008a2f4 c0089f88 00008520 bec1fed4 0000860c 00008670 00000005
bf80: c002c044 4013365c c3c7bfa4 c3c7bf98 c008a3a8 c008a2b0 00000000 c3c7bfa8
bfa0: c002bea0 c008a394 bec1fed4 0000860c 00008720 00000002 bec1fee0 00000001
bfc0: bec1fed4 0000860c 00008670 00000002 00008520 00000000 4013365c bec1fea8
bfe0: 00000000 bec1fe84 0000266c 400c98e0 60000010 00008720 00000000 00000000

Backtrace: (回溯)
[] (first_drv_open+0x0/0x3c [first_drv]) from [] (chrdev_open+0x14c/0x164)
[] (chrdev_open+0x0/0x164) from [] (__dentry_open+0x100/0x1e8)
r8:c3e766a8 r7:c0474e20 r6:c008d73c r5:c3e740c0 r4:c049abc0
[] (__dentry_open+0x0/0x1e8) from [] (nameidata_to_filp+0x34/0x48)
[] (nameidata_to_filp+0x0/0x48) from [] (do_filp_open+0x40/0x48)
r4:00000002
[] (do_filp_open+0x0/0x48) from [] (do_sys_open+0x54/0xe4)
r5:bec1fee0 r4:00000002
[] (do_sys_open+0x0/0xe4) from [] (sys_open+0x24/0x28)
[] (sys_open+0x0/0x28) from [] (ret_fast_syscall+0x0/0x2c)
Code: e24cb004 e59f1024 e3a00000 e5912000 (e5923000)
Segmentation fault

b. 编入内核
Modules linked in:
CPU: 0 Not tainted (2.6.22.6 #2)
PC is at first_drv_open+0x18/0x3c
LR is at chrdev_open+0x14c/0x164
pc : [] lr : [] psr: a0000013
sp : c3a03e88 ip : c3a03e98 fp : c3a03e94
r10: 00000000 r9 : c3a02000 r8 : c03f3c60
r7 : 00000000 r6 : 00000000 r5 : c38a0c50 r4 : c3c1e780
r3 : c014e6a8 r2 : 56000050 r1 : c031a47c r0 : 00000000
Flags: NzCv IRQs on FIQs on Mode SVC_32 Segment user
Control: c000717f Table: 339f0000 DAC: 00000015
Process firstdrvtest (pid: 750, stack limit = 0xc3a02258)

  1. 根据pc值确定该指令属于内核还是外加的模块
    pc=c014e6c0 属于内核(看System.map)

  2. 反汇编内核: arm-linux-objdump -D vmlinux > vmlinux.dis
    在dis文件里搜c014e6c0
    c014e6a8 <first_drv_open>:
    c014e6a8: e1a0c00d mov ip, sp
    c014e6ac: e92dd800 stmdb sp!, {fp, ip, lr, pc}
    c014e6b0: e24cb004 sub fp, ip, #4 ; 0x4
    c014e6b4: e59f1024 ldr r1, [pc, #36] ; c014e6e0 <.text+0x1276e0>
    c014e6b8: e3a00000 mov r0, #0 ; 0x0
    c014e6bc: e5912000 ldr r2, [r1]
    c014e6c0: e5923000 ldr r3, [r2] // 在此出错 r2=56000050

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值