AKever

导航

TQ2440 应用调试之配置修改内核打印用户态段错误信息

TQ2440 应用调试之配置修改内核打印用户态段错误信息

====================================

1. linux-2.6.30.4/arch/arm/mm/fault.c

__do_user_fault(struct task_struct *tsk, unsigned long addr,
unsigned int fsr, unsigned int sig, int code,
struct pt_regs *regs)
{
struct siginfo si;

#ifdef CONFIG_DEBUG_USER // 1. 配置内核
if (user_debug & UDBG_SEGV) {
printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
tsk->comm, sig, addr, fsr);
show_pte(tsk->mm, addr);
show_regs(regs);
}
#endif

ps: 在内核menuconfig中搜索:"DEBUG_USER", 然后选中

2. linux-2.6.30.4/arch/arm/kernel/traps.c

#ifdef CONFIG_DEBUG_USER
unsigned int user_debug;

static int __init user_debug_setup(char *str)
{
    get_option(&str, &user_debug);
    return 1;
}
__setup("user_debug=", user_debug_setup);
#endif

ps: 设置uboot启动参数

3. 编译好内核,烧入开发板

//TQ2440 通过Nand读取挂载根文件系统
-> set bootargs noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 user_debug=0xff 
//网络启动
-> set bootargs console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.123:/work/nfs_root/first_fs ip=192.168.1.17 ipaddr=192.168.1.17 user_debug=0xff 

 

================================

4. 测试程序 test_debug.c

#include <stdio.h>

void C(int *p)
{
    *p = 0x12;
}


void B(int *p)
{
    C(p);
}

void A(int *p)
{
    B(p);
}

void A2(int *p)
{
    C(p);
}


int main(int argc, char **argv)
{
    int a;
    int *p = NULL;

    A2(&a);  // A2 > C
    printf("a = 0x%x\n", a);

    A(p);    // A > B > C

    return 0;
}

5. 编译test_debug.c & 静态编译test_debug.c

# arm-linux-gcc -o test_debug test_debug.c //默认动态编译,连接动态库
# arm-linux-gcc -o test_debug_static test_debug.c -static //静态连接,连接静态库

6. 反编译以上文件 test_debug & test_debug_static

# arm-linux-objdump -D test_debug > test_debug.dis
# arm-linux-objdump -D test_debug_static > test_debug_static.dis

7. 执行文件 ./test_debug  后,出错键输出栈信息,一下黑色部分

8. 动态编译程序出错后对报错信息分析

a = 0x12
pgd = c04c8000
[00000000] *pgd=33d08031, *pte=00000000, *ppte=00000000

Pid: 772, comm:           test_debug
CPU: 0    Not tainted  (2.6.22.6 #1)
PC is at 0x84ac
LR is at 0x84d0
pc : [<000084ac>]    lr : [<000084d0>]    psr: 60000010
sp : bed9fe40  ip : bed9fe54  fp : bed9fe50
r10: 4013365c  r9 : 00000000  r8 : 00008514
r7 : 00000001  r6 : 000085cc  r5 : 00008568  r4 : bed9fec4
r3 : 00000012  r2 : 00000000  r1 : 00001000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode USER_32  Segment user
Control: c000717f  Table: 304c8000  DAC: 00000015
[<c002cd1c>] (show_regs+0x0/0x4c) from [<c0031a98>] (__do_user_fault+0x5c/0xa4)
 r4:c04a6840
[<c0031a3c>] (__do_user_fault+0x0/0xa4) from [<c0031d38>] (do_page_fault+0x1dc/0x20c)
 r7:c00261e0 r6:c0024cf8 r5:c04a6840 r4:ffffffec
[<c0031b5c>] (do_page_fault+0x0/0x20c) from [<c002b224>] (do_DataAbort+0x3c/0xa0)
[<c002b1e8>] (do_DataAbort+0x0/0xa0) from [<c002be48>] (ret_from_exception+0x0/0x10)
Exception stack(0xc3e7bfb0 to 0xc3e7bff8)
bfa0:                                     00000000 00001000 00000000 00000012 
bfc0: bed9fec4 00008568 000085cc 00000001 00008514 00000000 4013365c bed9fe50 
bfe0: bed9fe54 bed9fe40 000084d0 000084ac 60000010 ffffffff                   
 r8:00008514 r7:00000001 r6:000085cc r5:00008568 r4:c039bfc8
Segmentation fault

Stack: 
00000000 becd3e64 becd3e54 000084d0 000084a0 00000000 becd3e78 becd3e68 
C's sp                     return addr       B's sp

000084f0 000084c4 00000000 becd3e98 becd3e7c 00008554 000084e4 00000000 
ret addr          A's sp                     ret addr          main's sp

00000012 becd3ec4 00000001 00000000 becd3e9c 40034f14 00008524 00000000 
                                             ret addr          caller's sp
                                             对于动态链接,已经退出的程序不好确定动态库的地址

00000000 0000839c 00000000 00000000 4001d594 000083c4 000085cc 4000c02c 
becd3ec4 becd3f7b 00000000 becd3f88 becd3f92 becd3f99 becd3fad becd3fb8 

9. 静态编译程序出错后对报错信息分析

PC is at 0x81e0
LR is at 0x8204
pc : [<000081e0>]    lr : [<00008204>]    psr: 60000010
sp : be93dc60  ip : be93dc74  fp : be93dc70
r10: 000085f4  r9 : 00008248  r8 : be93deb4
r7 : 00000001  r6 : 00000000  r5 : be93dd3e  r4 : 00000000
r3 : 00000012  r2 : 00000000  r1 : 00001000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode USER_32  Segment user

Stack: 
00000000 be93dc84 be93dc74 00008204 000081d4 00000000 be93dc98 be93dc88 
C'sp                       ret addr          B'sp 

00008224 000081f8 00000000 be93dcb8 be93dc9c 00008288 00008218 00000000 
ret addr          A'sp                       ret addr          main'sp

00000012 be93deb4 00000001 00000000 be93dcbc 000084ac 00008258 756e694c 
                                             ret addr          __libc_start_main'sp

00000078 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 00000000 00000000 00000000 00000000 00000000 00000000 32393100 
3836312e 312e312e 00000037 00000000 00000000 00000000 00000000 00000000 

10. 对以上 9 确定地址位置发分析

      S1. test_debug_static.dis 部分代码

000081c4 <C>:
    81c4:    e1a0c00d     mov    ip, sp
    81c8:    e92dd800     stmdb    sp!, {fp, ip, lr, pc} //c1
    81cc:    e24cb004     sub    fp, ip, #4    ; 0x4
    81d0:    e24dd004     sub    sp, sp, #4    ; 0x4     //c2 分配空间 1*4=4
    81d4:    e50b0010     str    r0, [fp, #-16]
    81d8:    e51b2010     ldr    r2, [fp, #-16]
    81dc:    e3a03012     mov    r3, #18    ; 0x12
    81e0:    e5823000     str    r3, [r2]
    81e4:    e89da808     ldmia    sp, {r3, fp, sp, pc}

000081e8 <B>:
    81e8:    e1a0c00d     mov    ip, sp
    81ec:    e92dd800     stmdb    sp!, {fp, ip, lr, pc} //b1
    81f0:    e24cb004     sub    fp, ip, #4    ; 0x4
    81f4:    e24dd004     sub    sp, sp, #4    ; 0x4     //b2
    81f8:    e50b0010     str    r0, [fp, #-16]
    81fc:    e51b0010     ldr    r0, [fp, #-16]
    8200:    ebffffef     bl    81c4 <C>
    8204:    e89da808     ldmia    sp, {r3, fp, sp, pc}

00008208 <A>:
    8208:    e1a0c00d     mov    ip, sp
    820c:    e92dd800     stmdb    sp!, {fp, ip, lr, pc}  //a1
    8210:    e24cb004     sub    fp, ip, #4    ; 0x4
    8214:    e24dd004     sub    sp, sp, #4    ; 0x4      //a2
    8218:    e50b0010     str    r0, [fp, #-16]
    821c:    e51b0010     ldr    r0, [fp, #-16]
    8220:    ebfffff0     bl    81e8 <B>
    8224:    e89da808     ldmia    sp, {r3, fp, sp, pc}
... ...
00008248 <main>:
    8248:   e1a0c00d    mov ip, sp
    824c:   e92dd800    stmdb   sp!, {fp, ip, lr, pc}    //m1
    8250:   e24cb004    sub fp, ip, #4  ; 0x4
    8254:   e24dd010    sub sp, sp, #16 ; 0x10           //m2 4*4=16
    8258:   e50b0010    str r0, [fp, #-16]
    825c:   e50b1014    str r1, [fp, #-20]

  a.  由报错的pc : [<000081e0>] 值确定报错位置在C函数

  b. 由c1, c2位置算出,<C>函数占用栈中的5个地址单位(到00081d4结束),倒数第二个为<C>函数返回地址  

  c. 查看<C>函数返回地址8204, 确定是<B>函数调用了<C>函数

  d. 由b1, b2位置算出,<B>函数占用栈中的5个地址单位(到000081f8结束),倒数第二个为<B>函数返回地址  

  e. 查看<B>函数返回地址8224, 确定是<A>函数调用了<B>函数

  f. 由a1, a2位置算出,<A>函数占用栈中的5个地址单位(到00008218结束),倒数第二个为<A>函数返回地址 

  g. 查看<A>函数返回地址8288, 确定是main函数调用了<A>函数

  h. 由m1, m2位置算出,main函数占用栈中的8个地址单位(到00008258结束),倒数第二个为main函数返回地址 

  i. 查看main函数返回地址84ac, 在反汇编文件中不会找到,因为实在静态库里面调用了main函数

  j. 库反汇编文件 ld-linux.so.2.dis 部分代码,有该库调用了main函数

    84a4:    e5b43004     ldr    r3, [r4, #4]!
    84a8:    e3530000     cmp    r3, #0    ; 0x0
    84ac:    1affffec     bne    8464 <_dl_lookup_symbol_x+0x4a8>
    84b0:    e51b3078     ldr    r3, [fp, #-120]
    84b4:    e3530000     cmp    r3, #0    ; 0x0

 

 

=====================

--------------- The end!!

 

posted on 2016-10-29 19:02  AKever  阅读(380)  评论(0)    收藏  举报