リモートデバッガ/プロファイラを利用したデバッグ&性能解析

 ネットブックやMIDといったリソースの少ないマシンで動作するアプリケーションをデバッグする場合、実行環境とは異なるマシンでアプリケーションの動作状況をモニタリングするリモートデバッグが有用だ。本記事ではGDBや「インテル アプリケーション・デバッガー」でリモートデバッグを行う基本的な手順を紹介するとともに、「インテル VTune パフォーマンス・アナライザー」を用いたパフォーマンス解析についても紹介する。

 作成したアプリケーションに問題などが発生した場合によく使われるのが、デバッガを用いて問題発生個所周辺を追跡する手法だ。一般的なアプリケーションに対してデバッガを利用する場合、通常はアプリケーションを実行するマシン上でデバッグを行うことが多い。しかし、組み込みシステムやMIDなどユーザーインターフェイスを備えていない、もしくはリソースが少ない環境で動作するアプリケーションをデバッグする場合は、アプリケーションとデバッガを異なるマシン上で実行する「リモートデバッグ」と呼ばれる手法がよく利用される。

 リモートデバッグではアプリケーションを実行するマシンとデバッグ操作を行うマシンを何らかの方法で接続しデバッグを行う。一般的な接続方法としてはTCP/IPネットワークやシリアルケーブルなどが挙げられるが、以下では主にTCP/IPネットワーク経由でリモートデバッグを行う方法について解説していく。

図1 GUIによるリモートデバッグが行える「インテル アプリケーション・デバッガー」
図1 GUIによるリモートデバッグが行える「インテル アプリケーション・デバッガー」

 なお、以下ではアプリケーションを実行する側のマシンを「リモート」、デバッガを操作する側のマシンを「ホスト」と呼ぶことにする。またリモート側の環境では「Moblin 2.1 Netbooks and Nettops Project Release」を、ホスト側はMoblin開発に必要な環境を構築したUbuntu 9.04環境を使用している(図2)。

図2 記事中で使用したリモートデバッグ環境
図2 記事中で使用したリモートデバッグ環境

リモートデバッグのための準備

 リモートデバッグを行う場合、いくつかの事前準備が必要だ。まず、デバッグ対象とするアプリケーションはデバッグオプション付きでコンパイルされている必要がある。GCCやインテル コンパイラーでは、「-g」というデバッグオプションがこれに当たる。また、最適化が行われているとソースコードの追跡が難しくなる場合があるので、「-O0」オプションを指定して最適化を無効にしておくと良いだろう。

 リモートデバッグの際はリモート側とホスト側の両方にデバッグ対象とするアプリケーションの実行ファイルが必要である。さらにデバッグ中にソースコードの参照を行う場合は、ホスト側にソースコード一式が存在する必要がある。ホスト側のマシンでコンパイルを行うクロスコンパイル開発の場合は問題にならないが、リモート側でコンパイルを行っている場合はホスト側にバイナリやソースコードを適宜コピーしておく必要がある。

 そのほか、GUIを利用するアプリケーションをデバッグする場合、SSHでリモートログインしてデバッグ用サーバーを立ち上げるとアプリケーションのウィンドウがホスト側に表示されてしまうことがある。そのため、リモートログイン後に次のコマンドを実行し、ウィンドウをリモート環境で表示するように設定しておこう。

$ xhost +
$ export DISPLAY=:0.0

GDBでのリモートデバッグ

 インテル アプリケーション・デバッガーについて紹介する前に、まずはLinuxアプリケーション開発で事実上の標準デバッガとなっているGDBでのリモートデバッグ方法を簡単に述べておこう。GDBでは、アプリケーションを実行させる環境において「gdbserver」というデバッグ用サーバーを実行させ、ホストからこのサーバーにアクセスしてデバッグ操作を実行する。今回使用しているMoblinの場合、gdbserverはターミナルからyumコマンドを実行することでインストールできる。

$ sudo yum install gdb-gdbserver

 gdbserverによるリモートデバッグでは、まずリモート側で通信に使用するポート番号とデバッグするプログラムを引数に与えてgdbserverを実行する。たとえば8080番ポートを使用し、「/usr/local/bin/helloworld」をデバッグするには次のようにする。

$ gdbserver localhost:8080 /usr/local/bin/helloworld
Process /usr/local/bin/helloworld created; pid = 1512
Listening on port 8080

 続いて、ホスト側でgdbを起動する。この際、引数にはデバッグ対象のアプリケーションのバイナリを指定する。

$ gdb helloworld
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
 :
 :

 gdbが起動したら、「target remote <IPアドレス>:<ポート>」コマンドを実行してリモートのgdbserverに接続する。

(gdb) target remote 172.17.4.83:8080
Remote debugging using 172.17.4.83:8080
[New Thread 1512]
0x008ab850 in ?? ()

 あとは通常のデバッグと同様だ。たとえば「list」コマンドを実行すれば、現在実行している個所のソースコードが表示される。

(gdb) list
174	            clutter_main_quit ();
175	            return TRUE;
176	        }
177	    }
178	    return FALSE;
179	}
180
181	int main (int argc, char **argv)
182	{
183	    const ClutterColor scn_bkgd = {0x00,0x00,0xFF,0xFF};
(gdb)