2010年10月14日

gdb - リモートデバッグ

gdbを使ってリモートデバッグを行う手順例を示す。


 

ロスプラットフォームでの開発や、CUIアプリの実際の実行画面を確認しながらのデバッグを行いたい場合にリモートデバッグを使う。

 

環境

 
+-------+    +---------+
|デバッグ|--->|デバッグ  |
|ホスト  |    |ターゲット|
+-------+    +---------+

実行例

デバッグターゲットとデバッグホストが同じだが、2つの端末を用いた例を解説。例は、端末1と端末2の2つの端末が同一マシンの同一ユーザにログインしている状態とする。

     
  • 端末1(デバッグターゲット)でテストプログラムを作成    
    guest@debian5:~$ cat tst.c
    #include <stdio.h>

    int main()
    {
            printf("h"); fflush(stdout);
            printf("e"); fflush(stdout);
            printf("l"); fflush(stdout);
            printf("l"); fflush(stdout);
            printf("o"); fflush(stdout);
            printf(" "); fflush(stdout);
            printf("w"); fflush(stdout);
            printf("o"); fflush(stdout);
            printf("r"); fflush(stdout);
            printf("l"); fflush(stdout);
            printf("d"); fflush(stdout);
            printf("\n"); fflush(stdout);

            return 0;
    }

    guest@debian5:~$ gcc -g tst.c -o tst
    guest@debian5:~$


     

     
  • 端末1(デバッグターゲット)でgdbserverを起動    
    guest@debian5:~$ gdbserver localhost:1234 tst
    Process tst created; pid = 3181
    Listening on port 1234
     
     
  • 端末2(デバッグホスト)でgdbを起動    
    guest@debian5:~$ gdb ./tst
    GNU gdb 6.8-debian
    Copyright (C) 2008 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i486-linux-gnu"...
    (gdb) break main
    Breakpoint 1 at 0x8048415: file tst.c, line 5.
    (gdb) target remote localhost:1234
    Remote debugging using localhost:1234
    [New Thread 3181]
    0xb7f07810 in ?? () from /lib/ld-linux.so.2
    (gdb) c
    Continuing.

    Breakpoint 1, main () at tst.c:5
    5               printf("h"); fflush(stdout);
    (gdb) s
    6               printf("e"); fflush(stdout);
    (gdb)
    7               printf("l"); fflush(stdout);
    (gdb)
    8               printf("l"); fflush(stdout);
    (gdb)
    9               printf("o"); fflush(stdout);
    (gdb)
    10              printf(" "); fflush(stdout);
    (gdb)
    11              printf("w"); fflush(stdout);
    (gdb)
    12              printf("o"); fflush(stdout);
    (gdb)
    13              printf("r"); fflush(stdout);
    (gdb)
    14              printf("l"); fflush(stdout);
    (gdb)
    15              printf("d"); fflush(stdout);
    (gdb)
    16              printf("\n"); fflush(stdout);
    (gdb)
    18              return 0;
    (gdb)
    19      }
    (gdb)
    0xb7dbb455 in __libc_start_main () from /lib/i686/cmov/libc.so.6
    (gdb) c
    Continuing.

    Program exited normally.
    (gdb)


     

     
  • 端末1(デバッグターゲット)の表示に以下が追加される(特に"hello world"が端末2のステップ実行に合わせて1文字づつ表示されている状況が必見)    
    Remote debugging from host 127.0.0.1
    hello world

    Child exited with retcode = 0

    Child exited with status 0
    GDBserver exiting
    guest@debian5:~$


     

     
  • 因みに、リモートデバッグをやらずにローカルで直接デバッグすると以下の様になる。 ※"hello world"がデバッガの出力と混ざってしまっている。    
    guest@debian5:~$ gdb ./tst
    GNU gdb 6.8-debian
    Copyright (C) 2008 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i486-linux-gnu"...
    (gdb) break main
    Breakpoint 1 at 0x8048415: file tst.c, line 5.
    (gdb) r
    Starting program: /home/guest/tst

    Breakpoint 1, main () at tst.c:5
    5               printf("h"); fflush(stdout);
    (gdb) s
    h6              printf("e"); fflush(stdout);
    (gdb)
    e7              printf("l"); fflush(stdout);
    (gdb)
    l8              printf("l"); fflush(stdout);
    (gdb)
    l9              printf("o"); fflush(stdout);
    (gdb)
    o10             printf(" "); fflush(stdout);
    (gdb)
    11             printf("w"); fflush(stdout);
    (gdb)
    w12             printf("o"); fflush(stdout);
    (gdb)
    o13             printf("r"); fflush(stdout);
    (gdb)
    r14             printf("l"); fflush(stdout);
    (gdb)
    l15             printf("d"); fflush(stdout);
    (gdb)
    d16             printf("\n"); fflush(stdout);
    (gdb)

    18              return 0;
    (gdb)
    19      }
    (gdb)
    0xb7e6f455 in __libc_start_main () from /lib/i686/cmov/libc.so.6
    (gdb) c
    Continuing.

    Program exited normally.
    (gdb)


     

備考

     
  • RHELをターゲットにリモートデバッグを行うとSIGTRAPが大量に発生する。正しい対処法かどうかはわからないが、以下で抑制可能。    
    (gdb) handle SIGTRAP nostop noprint nopass
    SIGTRAP is used by the debugger.
    Are you sure you want to change it? (y or n) y

    Signal        Stop      Print   Pass to program Description
    SIGTRAP       No        No      No              Trace/breakpoint trap
    (gdb)


     

参考資料

     
  • "info gdb"の"Remote Debugging"

0 件のコメント:

コメントを投稿