アドオンシナリオのリモートデバッグ

PaPeRo iでC言語で作成したアドオンシナリオをgdbserverを使ってUbuntuホストから
リモートデバッグする方法を紹介します。

デバッグ用のlibpthreadをロードさせる

いきなり面倒な話なのですが、PaPeRo iの/lib/libpthread-2.14.sostripされているのですが、
そうするとgdb/gdbserverによるマルチスレッドプログラムのデバッグはできないらしいのです。
アドオンシナリオで意識的にスレッドを使っていなくても、アドオンシナリオはマルチスレッドの
sys_mgrからロードされて動作しますので、やっぱりデバッグできません。
そこでまずstripされていないlibpthreadを用意し、sys_mgrがそれを読み込んで起動する様に
起動スクリプトを修正する必要があります。
stripされていないデバッグ用libpthreadはここからダウンロードしてください。
このlibpthread.so_.tgzを/tmpに転送し、以下の手順で設定します。

# mkdir /Extension/local/lib
# cd /Extension/local/lib
# tar xvzf /tmp/libpthread.so_.tgz
# mv libpthread.so libpthread_nostrip.so
# ln -s libpthread_nostrip.so libpthread.so
# ln -s libpthread_nostrip.so libpthread.so.0
# ln -s libpthread_nostrip.so libpthread-2.14.so

起動スクリプト/Extension/script/S99-robotでLD_LIBRARY_PATHを設定している部分を修正し、
こちらのlibpthreadを読み込むようにします。

修正前:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Extension/robot_platform/lib:/Extension/robot_platform/lib/addon

修正後:

export LD_LIBRARY_PATH=/Extension/local/lib:$LD_LIBRARY_PATH:/Extension/robot_platform/lib:/Extension/robot_platform/lib/addon

修正したらPaPeRo iを再起動しておきます。

gdbserverの起動

gdbserverはopkgでインストールしてください。

# opkg update
# opkg install gdbserver

sys_mgrのPIDをps -ef | grep sys_mgrで調べておき、以下の様に起動します。

# gdbserver 0.0.0.0:5000 --attach sys_mgrのPID

※5000は任意のポート番号です

ホスト側でのデバッグ手順

gdb-multiarchを使うのでインストールしていない場合以下の様にインストールします。

Ubuntu $ sudo apt-get install gdb-multiarch

ホストのアドオンシナリオのソースがある場所にPaPeRo iから
/Extension/robot_platform/bin/sys_mgrをコピーしておきます。

デバッグを開始するには以下の手順を行います。

Ubuntu $ cd アドオンシナリオのソースがあるディレクトリ
Ubuntu $ gdb-multiarch sys_mgr
Ubuntu (gdb) target remote PaPeRoのIPアドレス:5000
Ubuntu (gdb) set sysroot remote:/
Ubuntu (gdb) break FUNCNAME   #アドオンシナリオsce_xxxxxxxxの関数
Ubuntu (gdb) cont

sys_mgrが起動した状態でのデバッグ開始となるため初期化処理のデバッグは出来ず、
起動した状態でブレークポイントを設定してブレークさせられる場所からしか
デバッグ開始できません。
また、リモートデバッグではrunコマンドは使えず、remoteコマンドでattachして
contするという手順となり、一度quitしてやり直す場合、PaPeRo i上のgdbserverの起動も
やり直す必要があります。
実際使ってみるとnext連続で固まってしまう現象がたまに発生しますが、
ブレークポイントを設定してcontさせる分には問題無いようです。

cgdb

gdbにはいくつかGUIフロントエンドが存在しますが、Ubuntu12.04と
Ubuntu14.04についてそれぞれemacs23、emacs24、ddd、cgdbを調べたところ、
全く使えない、またはコメントの日本語を表示出来ないものが多く、
なんとか使えるのはUbuntu12.04/14.04のemacs23(gud)とUbuntu12.04のcgdbだけでした。
いずれもGUIとはいってもキャラクタベースですが、コマンドラインのみに比べれば
だいぶデバッグ効率が上がると思います。
emacsは使う人を選ぶので、ここではcgdbの使い方について紹介します。
なおUbuntu14.04のcgdbでは日本語が表示出来なくなっていますが、
Ubuntu12.04のcgdbをそのまま動かすことは可能でした。

インストールは以下の様にapt-getでできます。

Ubuntu $ sudo apt-get install cgdb

デバッグ開始はgdb-multiarchの代わりに以下の様にします。

Ubuntu $ cgdb -d gdb-multiarch -- -ex "target remote PaPeRoのIPアドレス:5000" -ex "set sysroot remote:/" sys_mgr

キーバインドはこちらにわかりやすくまとめてくれている方がいらっしゃいました。

CGDBのショートカット一覧 – たいしょー(miettal)の日記

[参考] PaPeRo i上でgdb

リモートデバッグではなくPaPeRo i上でgdbを動作させることも可能です。
実はこちらはちゃんと動作確認しておらず、使い物になるかわからないのですが、
attach後にシンボルを読み込ませる方法が非常に見つけづらいのでその方法
だけでもご紹介します。

# opkg update
# opkg install gdb
# gdb /Extension/robot_platform/bin/sys_mgr
(gdb) attach sys_mgrのPID
(gdb) set solib-search-path

この場合NFSなどでアドオンシナリオのソースがPaPeRo i上から見える様にし、
それをgdbに教えてやる必要があります。
また、attachではなくrunで初期化処理のデバッグも可能なはずですが、
初期化スクリプト相当の処理を何らかの方法で実現する必要がある様です。


0