• 03.应用程序调试



    一、应用调试1:使用strace命令来跟踪系统调用
    1.strace移植

    cd /work/debug/strace-4.5.15

    tar xjf strace-4.5.15.tar.bz2

    cd strace-4.5.15

    patch -p1 ../strace-fix-arm-bad-syscall.patch

    配置

    ./configure --host=arm-linux CC=arm-linux-gcc

    编译

    make

    会生成一个strace的可执行文件,将其复制到文件系统的/bin目录下即可。

    2.程序测试

    strace -o log.txt ./firstdrvtest on

    vi log.txt可以得到以下结果

     1 execve("./firstdrvtest", ["./firstdrvtest", "on"], [/* 7 vars */]) = 0
     2 uname({sys="Linux", node="(none)", ...}) = 0
     3 brk(0)                                  = 0x11000
     4 access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
     5 open("/etc/ld.so.cache", O_RDONLY)      = -1 ENOENT (No such file or directory)
     6 open("/lib/v4l/half/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory
     7 stat64("/lib/v4l/half", 0xbea5e4f0)     = -1 ENOENT (No such file or directory)
     8 open("/lib/v4l/libc.so.6", O_RDONLY)    = -1 ENOENT (No such file or directory)
     9 stat64("/lib/v4l", 0xbea5e4f0)          = -1 ENOENT (No such file or directory)
    10 open("/lib/half/libc.so.6", O_RDONLY)   = -1 ENOENT (No such file or directory)
    11 stat64("/lib/half", 0xbea5e4f0)         = -1 ENOENT (No such file or directory)
    12 open("/lib/libc.so.6", O_RDONLY)        = 3
    13 read(3, "177ELF111a3(1330o100"..., 512) = 51
    14 fstat64(3, {st_mode=S_IFREG|0755, st_size=1435660, ...}) = 0
    15 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40
    16 mmap2(NULL, 1150612, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x4
    17 mprotect(0x40129000, 56980, PROT_NONE)  = 0
    18 mmap2(0x40131000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRI
    19 mmap2(0x40135000, 7828, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOU
    20 close(3)                                = 0
    21 open("/dev/xyz", O_RDWR)                = 3
    22 write(3, "1", 4)                 = 0
    23 exit_group(0)                           = ?
    测试程序

    分析可知程序出错都是由于没有相对应的文件所造成的,而且使用这种方法调试比较直观。


    二、应用调试2:使用GDB来调试应用程序

    编译gdb,gdbserver
    tar xjf gdb-7.4.tar.bz2
    cd gdb-7.4/
    ./configure --target=arm-linux
    make
    把arm-linux-gdb复制到/bin目录

    cd gdb/gdbserver/
    ./configure --host=arm-linux
    cp gdbserver /work/nfs_root/first_fs/bin

    编译要调试的应用,编译时加上-g选项

    调试:
    1. 在ARM板上
    gdbserver 192.168.1.17:2345 ./test_debug

    2. 在PC上
    /bin/arm-linux-gdb ./test_debug
    输入:target remote 192.168.1.17:2345
    然后: 使用gdb命令来控制程序


    另一种方法:
    让程序在开发板上直接运行,当它发生错误时,令它产生core dump文件
    然后使用gdb根据core dump文件找到发生错误的地方
    在ARM板上:
    1. ulimit -c unlimited
    2. 执行应用程序 : 程序出错时会在当前目录下生成名为core的文件

    在PC上:
    3. /bin/arm-linux-gdb ./test_debug ./core



    三、应用调试3:配置内核输出应用程序的段错误信息

    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 ",
                   tsk->comm, sig, addr, fsr);
            show_pte(tsk->mm, addr);
            show_regs(regs);
        }
    #endif

    2. uboot: set bootargs 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

    3. 执行APP
    ./test_debug
    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
    becd3fdb becd3fe9 00000000 00000010 00000003 00000006 00001000 00000011
    00000064 00000003 00008034 00000004 00000020 00000005 00000006 00000007
    40000000 00000008 00000000 00000009 0000839c 0000000b 00000000 0000000c
    00000000 0000000d 00000000 0000000e 00000000 00000017 00000000 0000000f
    becd3f77 00000000 00000000 00000000 00000000 76000000 2e006c34 7365742f
    65645f74 00677562 52455355 6f6f723d 4f480074 2f3d454d 61706900 3d726464
    2e323931 2e383631 37312e31 52455400 74763d4d 00323031 48544150 62732f3d
    2f3a6e69 2f727375 6e696273 69622f3a 752f3a6e 622f7273 53006e69 4c4c4548
    69622f3d 68732f6e 44575000 2e002f3d 7365742f 65645f74 00677562 00000000

    4. 反汇编app:
    arm-linux-objdump -D test_debug > test_debug.dis

    对于静态链接的test_debug
    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
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 2e320000
    32322e36 0000362e 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 23000000
    54203335 4d206575 31207961 31322035 3a34303a 43203834 32205453 00323130
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    766d7261 006c7434 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    6f6e2800 0029656e 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 000080f8 00008680 00000000 be93deb4 be93df6a 00000000 be93df77
    be93df81 be93df92 be93df99 be93dfad be93dfb8 be93dfdb be93dfe9 00000000
    00000010 00000003 00000006 00001000 00000011 00000064 00000003 00008034
    00000004 00000020 00000005 00000003 00000007 00000000 00000008 00000000
    00000009 000080d0 0000000b 00000000 0000000c 00000000 0000000d 00000000
    0000000e 00000000 00000017 00000000 0000000f be93df66 00000000 00000000
    00000000 34760000 2f2e006c 74736574 6265645f 55006775 3d524553 746f6f72
    444c4f00 3d445750 6f72702f 34372f63 4f480033 2f3d454d 61706900 3d726464
    2e323931 2e383631 37312e31 52455400 74763d4d 00323031 48544150 62732f3d
    2f3a6e69 2f727375 6e696273 69622f3a 752f3a6e 622f7273 53006e69 4c4c4548
    69622f3d 68732f6e 44575000 2e002f3d 7365742f 65645f74 00677562 00000000

    四、应用调试4:自制系统调用、编写进程查看器

    把29th_app_system_callkernel里的文件复制到内核目录
    syscalls.h    ==> include/linux
    read_write.c  ==> fs/
    calls.S       ==> arch/arm/kernel

    五、应用调试5:编写输入模拟器
    1. 产品要经过测试才能发布,一般都是人工操作,比如手机触摸屏、遥控器
    2. 操作过程中发现错误,要再次复现,找到规律,修改程序
    3. 能否在驱动程序里把所有的操作记录下来,存为文件
       当出错时,可以通过文件里的数据来"复现"输入
       
       input_event
       

  • 相关阅读:
    JZOJ 4.1 B组 删数
    JZOJ 4.1 B组 无限序列
    JZOJ 4.1 C组 【GDOI2005】电路稳定性
    JZOJ 4.1 C组【GDOI2005】积木分发
    SSL 1614——医院设置[最短路]
    SSL 1761——城市问题[最短路]
    SSL 1760——商店选址问题(最短路)
    SSL 1613——最短路径问题(最短路)
    JZOJ 3.25 1422——【汕头市选2012初中组】步行(walk)
    JZOJ 3.25 1421【汕头市选2012初中组】数数(count)
  • 原文地址:https://www.cnblogs.com/Lwd-linux/p/6361275.html
Copyright © 2020-2023  润新知