3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

gdbによるCプログラムのデバッグ

Last updated at Posted at 2019-11-18

gdbによるCプログラムのデバッグ

背景

  • IDEの無い環境でプログラムのデバッグが必要になった。
  • 対象はLinux上のgccでコンパイルしたプログラム。
  • cmakeでビルドしているため、デバッグオプションを適宜設定する必要がある。

cmakeのデバッグ設定

cmake -DCMAKE_BUILD_TYPE=Debug

  • NG: シンボル情報を生成してくれない

    (gdb) break main
    No symbol table is loaded.  Use the "file" command.
    

CMakeLists.txtを編集

  • OK: 以下の一行を追加(なるべく前のほうで)

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0")
    

gdbによるデバッグ例

  • デバッグ対象:Anjay
    • なんというか、LwM2Mのクライアント実装に興味があったので・・・
    • Apache 2.0ライセンスです。

起動・実行・継続・ステップIN・ステップOVER・ステップOUT・終了

  • 起動 (プログラム引数を与えて起動)

    • プロブラム本体: demo
    • プログラム引数1: --server-uri LwM2M Server URL
    • プログラム引数2: -e 登録名
    $ gdb --args ./demo --server-uri coap://leshan.eclipseprojects.io:5683 -e TETSUO_ANJAY_DEV0
    GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
    Copyright (C) 2018 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    ・・・(snip)
    
  • 実行

    (gdb) run
    Starting program: /home/tetsuo/Anjay/build/output/bin/demo --server-uri coap://leshan.eclipseprojects.io:5683 -e TETSUO_ANJAY_DEV0
    ・・・
    
  • 再開

    Breakpoint 1, main (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo.c:548
    548	int main(int argc, char *argv[]) {
    (gdb) continue
    Continuing.
    2019-11-18 18:11:26.841555 INFO [anjay] [/home/tetsuo/Anjay/src/anjay_core.c:172]: Initializing Anjay 1.16
    
  • ステップOVER

    • 関数呼び出しの中に入らず、現コードの次のステップに移動します。
    • 以下例では関数argv_storeの外側で1ステップ進みます。
    (gdb) next
    565	    for (int fd = 3, maxfd = (int) sysconf(_SC_OPEN_MAX); fd < maxfd; ++fd) {
    (gdb) next
    566	        close(fd);
    (gdb) next
    565	    for (int fd = 3, maxfd = (int) sysconf(_SC_OPEN_MAX); fd < maxfd; ++fd) {
    (gdb) next
    566	        close(fd);
  • ステップIN

    • 関数の呼び出しの中に移動します。
      • ブレークポイントargv_storeから、関数の中(demo_utils.c:44)に入っていきます。
    Breakpoint 2, main (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo.c:594
    594	    if (argv_store(argc, argv)) {
    (gdb) step
    argv_store (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo_utils.c:44
    44	    AVS_ASSERT(argc >= 0, "unexpected negative value of argc");
    (gdb) 
    
  • ステップOUT

    • 関数から出て、呼び出し元に戻ります。
      • 関数の中(demo_utils.c:44)から、呼び出し元(demo.c:594)に戻ります。
      • 関数の戻り値 (Value returned is $1 = 0)が表示されます。
    (gdb) step
    argv_store (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo_utils.c:44
    44	    AVS_ASSERT(argc >= 0, "unexpected negative value of argc");
    (gdb) fin
    Run till exit from #0  argv_store (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo_utils.c:44
    0x0000555555562e4f in main (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo.c:594
    594	    if (argv_store(argc, argv)) {
    Value returned is $1 = 0
    
  • 終了

  • (gdb) quit
    A debugging session is active.
    
        Inferior 1 [process 21171] will be killed.
    
    Quit anyway? (y or n) y
    tetsuo@trial19:~/Anjay/build/output/bin$ 
    

ブレークポイント

  • ブレークポイント(メソッド名)指定して、実行

      (gdb) break main
      Breakpoint 1 at 0xed72: file /home/tetsuo/Anjay/demo/demo.c, line 548.
      (gdb) run
      Starting program: /home/tetsuo/Anjay/build/output/bin/demo --server-uri coap://leshan.eclipseprojects.io:5683 -e TETSUO_ANJAY_DEV0
    
      Breakpoint 1, main (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo.c:548
      548	int main(int argc, char *argv[]) {
    
    
  • ブレークポイント(行番号)を指定して、継続

      (gdb) break demo.c:594
      Breakpoint 2 at 0x555555562e38: file /home/tetsuo/Anjay/demo/demo.c, line 594.
      (gdb) continue
      Continuing.
    
      Breakpoint 2, main (argc=5, argv=0x7fffffffe048) at /home/tetsuo/Anjay/demo/demo.c:594
      594	    if (argv_store(argc, argv)) {
    
    
  • ブレークポイント一覧表示

      (gdb) info breakpoints
      Num     Type           Disp Enb Address            What
      1       breakpoint     keep y   0x0000555555562d72 in main at /home/tetsuo/Anjay/demo/demo.c:548
          breakpoint already hit 1 time
      2       breakpoint     keep y   0x0000555555562e38 in main at /home/tetsuo/Anjay/demo/demo.c:594
          breakpoint already hit 1 time
    
    
  • 現在のブレークポイント(周辺)をソース上で確認

      (gdb) list
      589	    avs_log_set_handler(log_handler);
      590	    avs_log_set_default_level(AVS_LOG_TRACE);
      591	    avs_log_set_level(demo, AVS_LOG_DEBUG);
      592	    avs_log_set_level(anjay_sched, AVS_LOG_DEBUG);
      593	
      594	    if (argv_store(argc, argv)) {
      595	        return -1;
      596	    }
      597	
      598	    cmdline_args_t cmdline_args;
    
    

変数の入出力

  • 現在の変数の値を出力

      (gdb) print argc
      $9 = 5
      (gdb) print argv[0]
      $10 = 0x7fffffffe387 "/home/tetsuo/Anjay/build/output/bin/demo"
      (gdb) print argv[1]
      $11 = 0x7fffffffe3b0 "--server-uri"
      (gdb) print argv[2]
      $12 = 0x7fffffffe3bd "coap://leshan.eclipseprojects.io:5683"
      (gdb) print argv[3]
      $13 = 0x7fffffffe3e3 "-e"
      (gdb) print argv[4]
      $14 = 0x7fffffffe3e6 "TETSUO_ANJAY_DEV0"
    
    
  • 変数の値を変更

      (gdb) print argv[4]
      $14 = 0x7fffffffe3e6 "TETSUO_ANJAY_DEV0"
      (gdb) set argv[4] = "HOGEHOGE_DEV1"
      (gdb) print argv[4]
      $15 = 0x7ffff7fde940 "HOGEHOGE_DEV1"
    

その他機能

  • バックトレース(コールスタック)
    • ブレークポイントから呼び出し元を再帰的に表示
    • bt (backtrace)
(gdb) bt
#0  connect_udp_socket (anjay=0x555555802770, connection=0x5555558063d0)
    at /home/tetsuo/Anjay/src/servers/connection_udp.c:331
#1  0x00005555555a80c8 in _anjay_connection_internal_bring_online (anjay=0x555555802770, connections=0x5555558063d0, 
    conn_type=ANJAY_CONNECTION_UDP) at /home/tetsuo/Anjay/src/servers/connections.c:144
#2  0x00005555555a8666 in ensure_socket_connected (anjay=0x555555802770, connections=0x5555558063d0, 
    conn_type=ANJAY_CONNECTION_UDP, inout_info=0x7fffffff9ad0) at /home/tetsuo/Anjay/src/servers/connections.c:260
#3  0x00005555555a874d in refresh_connection (anjay=0x555555802770, connections=0x5555558063d0, 
    conn_type=ANJAY_CONNECTION_UDP, inout_info=0x7fffffff9ad0) at /home/tetsuo/Anjay/src/servers/connections.c:280
#4  0x00005555555a8837 in _anjay_connections_refresh (anjay=0x555555802770, connections=0x5555558063d0, security_iid=1, 
    uri=0x7fffffff9b30, binding_mode=0x7fffffff9c40 "U") at /home/tetsuo/Anjay/src/servers/connections.c:306
#5  0x0000555555586505 in _anjay_active_server_refresh (anjay=0x555555802770, server=0x5555558063c0)
    at /home/tetsuo/Anjay/src/servers/server_connections.c:128

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?