ブログ

Armadillo-440(Linux-3.14):gdbserverを使ってみました

at_kazutaka.bito
2016年7月2日 15時10分

Armadillo-440(Linux-3.14)でgdbserverを使ってみました。 gdbserver を使うことによって、Armadilloでイーサネット経由のリモートデバッグをすることができます。 (gdbの使い方については、gdb の使い方・デバッグ方法まとめを参考にさせていただきました。)

準備として、PCとArmadilo-440をLANケーブルで接続して、ATDE5とArmadilo-440がネットワークで通信できる状態にしておきます。

1.Armadillo-440で、gdbserverを有効にする

標準の設定では、gdbserverは有効になっていませんので、ユーザーランドコンフィギュレーションで追加します。

atmark@atde5:~/atmark-dist$ make menuconfig

で、コンフィギュレーションを開いて、

Main Menu
Kernel/Library/Defaults Selection --->
[*] Cutomize Vnedor/User Settings   // *を付ける

で、ユーザーランドコンフィギュレーションの設定画面に移動して、

Userland Configuration
MIscellaneous Application --->
[*] gdbserver             // *を付ける

で、gdbserverを有効にします。

上記の設定後、ビルドしたイメージをArmadillo-440に書き込みます。

2.動作確認用のプログラム

ここでは、下記のようなプログラムでgdbの動作確認を行いました。 ("Hello World!([回数], [回数の2倍])"を100回分表示するプログラムです。)

ATDE5上で下記のソースコードの"hello2.c"を作成します。 (ここでは、~/hello2ディレクトリ内で作成しました。)

atmark@atde5:~$ mkdir hello2
atmark@atde5:~$ cd hello2
atmark@atde5:~/hello2$ gedit hello2.c

で、エディタを開いて、"hello2.c"を下記のように記述します。

#include <stdio.h>
#include <stdlib.h>
 
int count_2up(int cnt) {
    cnt += 2;
    return cnt;
}
 
int main(int argc, char *argv[])
{
    int i;
    int cnt = 0;
 
     for(i = 0; i < 100; i++) {
         printf("Hello World!(%d, %d)\n", i , cnt);
        cnt = count_2up(cnt);
     }   
 
  return EXIT_SUCCESS;
}

ビルドします。(gdbでデバッグするために、-gオプションを付けています。)

atmark@atde5:~/hello2$ arm-linux-gnueabi-gcc -g hello2.c -o hello2

ビルドによって生成された実行ファイル"hello2"をArmadillo-440に置いて、実行権限を付けます。

[root@armadillo440-0 (ttymxc1) ~]# ls hello2
hello2
[root@armadillo440-0 (ttymxc1) ~]# chmod +x hello2

"hello2"を実行すると、下記のように"Hello World!([回数], [回数の2倍])"が100回分表示されます。

[root@armadillo440-0 (ttymxc1) ~]# ./hello2
Hello World!(0, 0)
Hello World!(1, 2)
Hello World!(2, 4)
(略)
Hello World!(97, 194)
Hello World!(98, 196)
Hello World!(99, 198)

3.gdbserverでリモートで動作確認

以下、 「192.168.11.35」をATDE5のIPアドレス 「192.168.11.36」をArmadillo-440のIPアドレス 「9876」をデバッグに使用するポート番号 の場合で説明しています。

Armadillo-440で、"hello2"に対して、gdebserverを起動します。 「192.168.11.35」をATDE5のIPアドレス 「9876」をデバッグに使用するポート番号

[root@armadillo440-0 (ttymxc1) ~]# gdbserver 192.168.11.35:9876 ./hello2
Process ./hello2 created; pid = 1877
Listening on port 9876

ATDE5で、"hello2"に対して、arm-linux-gnueabi-gdbを起動します。

atmark@atde5:~/hello2$ ls
hello2  hello2.c
atmark@atde5:~/hello2$ arm-linux-gnueabi-gdb ./hello2
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 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 "--host=x86_64-linux-gnu --target=arm-linux-gnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/atmark/hello2/hello2...(no debugging symbols found)...done.
(gdb) 

Armadillo-440をターゲットに設定します。 「192.168.11.36」をArmadillo-440のIPアドレス 「9876」をデバッグに使用するポート番号

(gdb) target remote 192.168.11.36:9876
Remote debugging using 192.168.11.36:9876
Reading symbols from /usr/arm-linux-gnueabi/lib/ld-linux.so.3...(no debugging symbols found)...done.
Loaded symbols for /usr/arm-linux-gnueabi/lib/ld-linux.so.3
0xb6fda7c0 in ?? () from /usr/arm-linux-gnueabi/lib/ld-linux.so.3

このとき、接続に成功すると、Armadillo-440側に

Remote debugging from host 192.168.11.35

というログが出力されます。

gdb の使い方・デバッグ方法まとめを参考にいくつかコマンドを試してみました。 ここでは、手順2のソースコードの5行目のcount_2up関数内の cnt += 2; に、ブレークをはって、cntの値を見てみました。 下記例では、

(gdb) b 5   // 5行目にブレークポイント
(gdb) p cnt  // 変数cntを表示
(gdb) c    // 処理を継続
(gdb) q    // gdbを終了

を行っています。

(gdb) b 5
Cannot access memory at address 0x0
Breakpoint 1 at 0x83e4: file hello2.c, line 5.
(gdb) p cnt
No symbol "cnt" in current context.
(gdb) c
Continuing.
 
Breakpoint 1, count_2up (cnt=0) at hello2.c:5
5        cnt += 2;
(gdb) c
Continuing.
 
Breakpoint 1, count_2up (cnt=2) at hello2.c:5
5        cnt += 2;
(gdb) c
Continuing.
 
Breakpoint 1, count_2up (cnt=4) at hello2.c:5
5        cnt += 2;
(gdb) q
A debugging session is active.
 
    Inferior 1 [Remote target] will be killed.
 
Quit anyway? (y or n) y