[Linux]GDBでバックトレースを確認(lcrashのデバッグ)

スポンサーリンク

GDBを使ってlcrashをデバッグしたときの話。

引数パラメータを設定して、lcrashを起動し、ブレイクポイントを張って、バックトレースを見たりしてデバックしていました。


  • 関数レベルのテストの例。
    ※lcrashは少し改造してあります。
  1. 起動とか引数設定とか
    > gdb ./lcrash
    GNU gdb 6.6
    Copyright (C) 2006 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i586-suse-linux"...
    Using host libthread_db library "/lib/libthread_db.so.1".
    (gdb) set args System.map dump_file Kerntypes
    (gdb) r
    Starting program: ./lcrash System.map dump_file Kerntypes
    lcrash 0.10.2 (xlcrash) build at Jan  9 2008 11:57:42
    Lcrash is free software. It is covered by the GNU General Public License.
    You are welcome to change it and/or distribute copies of it under certain
    conditions. Type "help -C" to see the conditions. Absolutely no warranty
    is given for Lcrash. Type "help -W" for warranty details.
          map = System.map
         dump = dump_file
    kerntypes = Kerntypes
    Please wait...
            Check dump architecture:
                    Dump arch set.
            Initializing host arch data ... Done.
            Initializing dump access data... Done.
            Opening dump for access... Done.
            Loading type info (Kerntypes) ... Done.
            Loading kernel symbol information ... Done.
            Initialize virtop address translator... Done.
            Initialize dump specific data ... Done.
            Loading ksyms from dump ... Failed.
    DUMP INFORMATION:
         architecture: arm
           byte order: little
         pointer size: 32
       bytes per word: 4
       kernel release: 2.6.21
          memory size: 67108864 (0G 64M 0K 0Byte)
       num phys pages: 16384
       number of cpus: 1
    >>
  2. lcrash起動状態時にgdbモードに戻すときは「Ctrl+C」を押す
    Program received signal SIGINT, Interrupt.
    0xffffe410 in __kernel_vsyscall ()
  3. ブレイクポイントの設定(Test1)
    (gdb) b dis_cmd
    Breakpoint 1 at 0x80f0491: file cmd_dis.c, line 35.
  4. 継続(continue) lcrash起動状態に戻る
    (gdb) c
    Continuing.
    >>
  5. 引数に与える関数を調べる(参考情報)
    >> vi -f System.map
  6. System.mapに記載されている関数を引数に指定してdisを実行
    >> dis -F start_kernel
  • ブレイクポイントで停止する
    Breakpoint 1, dis_cmd (cmd=0x83ae990) at cmd_dis.c:35
    35              char *c = (char *)NULL;
  1. 次のブレイクポイントを指定(Test2)
    (gdb) b print_instr_arm
    Breakpoint 2 at 0x8074a39: file dis_arm.c, line 146.
  2. 次のブレイクポイントまで実行(continue)
    (gdb) c
    Continuing.
    Breakpoint 2, print_instr_arm (pc=3221260832, ofp=0xb7f084e0, flag=0) at dis_arm.c:146
    146             bzero(&irp, sizeof(irp));
    (gdb) n
    151             get_instr_info_arm(pc, &irp);
  3. 次の関数(Test3)を見つけたのでステップ実行(step、s)
    (gdb) s
    get_instr_info_arm (pc=3221260832, irp=0xbfb6db70) at dis_arm.c:66
    66              FILE* tmpfile = NULL;
    (gdb) n
    68              if (irp == NULL) {
    (gdb)
    72              bzero(irp, sizeof(instr_rec_arm_t));
    (gdb)
    74              vma = pc;
    (gdb)
    75              GET_BLOCK(vma, 4, &irp->opcode);
    (gdb) s
    kl_get_block (addr=3221260832, size=4, bp=0xbfdeae04, mmap=0x0) at kl_mem.c:221
    221             kaddr_t vaddr=addr;
  4. バックトレース情報で確認(backtrace、bt)
    #3 → #2 → #1 → #0
    となっているので、項番8はOK

    (gdb) bt
    #0  kl_get_block (addr=3221260832, size=4, bp=0xbfdeae04, mmap=0x0) at kl_mem.c:221
    #1  0x08074734 in get_instr_info_arm (pc=3221260832, irp=0xbfdeadf0) at dis_arm.c:75
    #2  0x08074a7c in print_instr_arm (pc=3221260832, ofp=0xb7f224e0, flag=0) at dis_arm.c:151
    #3  0x080f069e in dis_cmd (cmd=0x83ae990) at cmd_dis.c:88
    #4  0x080ee976 in do_cmd (cmd=0x83ae990) at command.c:470
    #5  0x080eea10 in process_cmds () at command.c:497
    #6  0x0805e91f in main (argc=4, argv=0xbfdeb824) at main.c:734
    (gdb)

    以下、参考

    (gdb) n
    223             if (!bp) {
    (gdb)
    225             } else if (!size) {
    (gdb)
    266                     while (size > 0){
    (gdb)
    267                             s=((vaddr & KL_PAGE_MASK) | (~KL_PAGE_MASK)) -
    (gdb)
    269                             s= (size > s) ? s : size;
    (gdb)
    270                             vaddr = KL_FIX_VADDR(vaddr, s);
    (gdb)
    271                             if(KL_VIRTOP(vaddr, mmap, &paddr) ) {
    (gdb)
    287                                     if(kl_readmem(paddr, s, bp)){

コメント

タイトルとURLをコピーしました