HPC/並列プログラミングポータルでは、HPC(High Performance Computing)プログラミングや並列プログラミングに関する情報を集積・発信しています。

新着トピックス

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

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

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

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

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

インテル アプリケーション・デバッガーを使用したデバッグ

 インテル アプリケーション・デバッガーは、インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートに付属するデバッガだ。標準でGUIによる操作に対応しており、ローカルで実行するアプリケーションだけでなく、リモートデバッグにも対応している。インテル アプリケーション・デバッガーは、通常/opt/intel/atom/idb/<バージョン番号>以下にインストールされている。

 インテル アプリケーション・デバッガーでリモートデバッグを行う場合、リモートマシン上でサーバープログラムを実行しておく必要がある。サーバープログラムはインストールディレクトリ以下の「server」ディレクトリ内に「idbserver_LINUX32」という名前でインストールされているので、これをリモートマシンの適当なディレクトリにコピーする。

cd /opt/intel/atom/idb/2.1.008
scp idbserver_LINUX32 <リモートマシンのIPアドレス>:~/

 次に、リモートマシン側でコピーしたサーバープログラムを実行する。この際、特に引数等を与える必要はない。

$ ./idbserver_LINUX32
Intel(R) Debugger Remote Server for IA32 Linux, Version 1.1.2
Copyright (C) 2006-2009 Intel Corporation. All rights reserved.

Waiting for connection with "tcpip:2000"...  ←使用するポート番号が表示される

 リモート側でサーバーを起動したら、続いてホスト側でインテル アプリケーション・デバッガーを起動する。インストールディレクトリ以下の「bin」ディレクトリにある「idb.sh」が、インテル アプリケーション・デバッガーを起動するためのスクリプトだ。

$ /opt/intel/atom/idb/<バージョン番号>/bin/idb.sh

 インテル アプリケーション・デバッガーが起動したら、「File」メニューの「Connect」を選択する。「Connect」ダイアログが表示されるので、「Hostname / IP Address」欄にリモートマシンのIPアドレスを、「Port Number」に使用するポート番号を入力し、「OK」をクリックしてサーバーに接続しよう。

 サーバーへの接続が成功すると、「File」メニューの「Open Executable」や「Attach To Process」、「Execute Command File」などが選択できるようになる(図3)。リモートデバッグを開始するには、ここで「Open Executable」を選択する。

 「File」メニューの「Open Executable」を選択すると、「Open Executable」ダイアログが表示されるので、ここで実行するアプリケーションなどを設定する(図4)。必要な設定項目は次の表1のとおりだ。

表1 インテル アプリケーション・デバッガーの「Open Executable」ダイアログで設定すべき項目
項目名説明
Executable Fileデバッグ対象とする実行ファイル(ホスト側)
Remote Executable Fileリモート側で実行するファイル
Argumentsタブアプリケーションに与える引数や作業ディレクトリ
Environmentタブ実行時の環境変数
Source Directoriesソースコードが格納されたディレクトリ

 以上を指定して「OK」をクリックすると実行ファイルがロードされる。

インテル アプリケーション・デバッガーの基本操作

 以上の設定が完了した状態で「Run」メニューの「Run Or Rerun」を選択するとデバッグが開始される。プログラムの実行を一時停止したり、ステップ実行といったデバッグ操作は「Run」メニューから行える。

 ソースコード中でブレークポイントを指定するには、まず「View」メニューの「Source Files」を選択してソースファイル一覧を開き、ブレークポイントを設定したいファイルをダブルクリックして表示させる。次にソースコード中でブレークポイントを設定したい個所を右クリックし、メニューから「Set Breakpoint」を選択すれば良い(図5)。

 デバッグの実行中は「View」メニュー内の「Callstack」や「Locals」といった項目が選択可能になり、実行中アプリケーションのさまざまな状態が確認できるようになる(図6、'表2)。

表2 インテル アプリケーション・デバッガーで確認できる項目
項目名説明
Consoleデバッグコンソール
Breakpointブレークポイント一覧
Callstackコールスタック情報
Localsローカル変数の値
Source Filesソースファイル一覧
Threads実行されているスレッド一覧
Memoryアドレスを指定してメモリ内に記録されている情報を閲覧
Registersレジスタの状態
Assembler実行中のアセンブラコード

インテル VTune パフォーマンス・アナライザーを使用したプロファイリング

 アプリケーションの不具合や意図しない動作など、問題点を調べる際にデバッガは有用である。いっぽう、アプリケーションのパフォーマンスチューニングの際に有用なツールが「プロファイラ」と呼ばれるものだ。プロファイラはプログラムのどの部分がどれだけ実行されているのか、またどの関数がどの関数を呼んでいるのかなど、プログラムの実行状況を測定するツールである。

 インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートには、「インテル VTune パフォーマンス・アナライザー」(以下、VTune)というプロファイラが付属しており、こちらを利用することでGUI画面でアプリケーションの実行状況やボトルネックになっている部分の検出など、パフォーマンスの解析を行える(図7)。

 VTuneの機能詳細については「パフォーマンス解析ツール「VTune」でアプリケーションを高速化」という記事で詳しく解説しているが、インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートに付属するVTuneはクロスプラットフォーム開発とテスト、MIDのチューニングに向けた機能限定版であり、そのためインストールや設定方法などが若干異なっている点に注意してほしい。具体的には、インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートに付属するVTuneではサンプルデータの取得方法として「Intel VTune Performance Analyzer Sampling Collector」のみをサポートしており、GUIでのサンプリングデータ取得操作は行えない。それ以外、たとえばサンプリング結果の閲覧・分析などについては単独版のVTuneと同様に行える。

リモートマシンへの「Intel VTune Performance Analyzer Sampling Collector」のインストール

 インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートに付属するVTuneでは、「Intel VTune Performance Analyzer Sampling Collector」と呼ばれるサンプリングツールをリモートマシンにインストールし、これを実行してサンプルデータを取得するのだが、Intel VTune Performance Analyzer Sampling Collectorのインストールにはカーネルモジュールのコンパイルが必要で、若干面倒である。そこで、初めにMoblin環境に向けてIntel VTune Performance Analyzer Sampling Collectorのインストールと、これらカーネルモジュールのコンパイルを行う手順を解説しておこう。

 Intel VTune Performance Analyzer Sampling Collectorのインストーラおよびファイル一式は、インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートの配布アーカイブ内「rpm」ディレクトリ内に「vtune91u5_target.tar.gz」ファイルとして格納されている。まずはこのファイルをリモートマシンにSCPなどを使用してコピーする。

$ cd rpm
$ scp vtune91u5_target.tar.gz <リモートマシンのIPアドレス>:

 続いてリモートマシン側でこのアーカイブを展開し、含まれるインストールスクリプト(install-vtune-sep.sh)を実行する。

$ tar xvzf vtune91u5_target.tar.gz
$ cd vtune91u5_target
$ ./install-vtune-sep.sh
NOTE:  super-user or "root" privileges are required in order to continue.
Please enter "root" Password:

The following product will be installled:

    Intel(R) VTune(TM) Performance Analyzer 9.1u5 sampling utility for Linux

Press ENTER to review the end user license agreement or Ctrl-C to exit ...
 :
 :

 インストールスクリプトを実行すると、初めにルートパスワードが要求される。これを入力し、あとは指示に従ってインストール作業を進めて行こう。インストールの完了後、デフォルトでは「/opt/intel/vtune」以下にIntel VTune Performance Analyzer Sampling Collector一式が格納されているはずだ。

 なお、デフォルト設定ではインストール作業の最後にカーネルモジュールのコンパイルが行われるのだが、GCCやカーネルヘッダーなど必要なツールやファイルがない場合コンパイルは行われない。この場合、後述する方法で別途カーネルモジュールのコンパイルやインストールを行う必要がある。

 また、サンプリングの実行は、インストール時に指定したグループ(デフォルトでは「users」)に所属しているユーザーで行う必要がある。「/etc/group」ファイルを編集し、サンプリングを実行するユーザーをそのグループに所属させておこう。

$ sudo vim /etc/group
 :
 :
nobody:x:99:
users:x:100:  ←この行の最後にサンプリングを実行するユーザー名を追加する
utmp:x:22:
utempter:x:35:
ntp:x:38:
slocate:x:21:
 :
 :

カーネルモジュールのコンパイルとインストール

 Intel VTune Performance Analyzer Sampling Collectorのインストール時にカーネルモジュールをコンパイルしなかった場合、別途カーネルモジュールを用意する必要がある。これにはさまざまな方法があるが、ここではMoblin SDKに付属するMoblinのルートファイルシステムを利用し、chrootを使用してクロスコンパイルを行う例を紹介する。なお、下記ではMoblin SDKを‾/moblin-sdk-0.10以下にインストールした場合を想定している。それ以外のディレクトリにインストールしている場合は、適宜環境に合わせてこれを変更してほしい。

 まず、Intel VTune Performance Analyzer Sampling CollectorのアーカイブをMoblinルートファイルシステム以下にコピーしておく。

$ cp vtune91u5_target.tar.gz ~/moblin-sdk-0.10/moblin-cross-toolchain/i586-moblin-linux/sys-root/root

 次にMoblin SDK内のMoblinルートファイルシステムが格納されたディレクトリに移動し、procおよびdevディレクトリを作成して/procおよび/devにバインドしておく。

$ cd ‾/moblin-sdk-0.10/moblin-cross-toolchain/i586-moblin-linux/sys-root
$ mkdir proc
$ mkdir dev
$ sudo mount --bind /dev dev
$ sudo mount --bind /proc proc

 また、chroot環境からネットワーク接続が利用できるよう、「resolv.conf」ファイルをコピーしておく。

$ sudo cp /etc/resolv.conf etc/

 以上を実行したのち「sudo chroot」を実行すると、Moblin SDKのルートファイルシステムを仮想的にルートディレクトリとする環境(以下、chroot環境と呼ぶ)に入ることができる。

$ sudo chroot .

 次に、chroot環境内にIntel VTune Performance Analyzer Sampling Collectorをインストールする。基本的な手順はリモートマシンへのインストールと同じだ。ただし、カーネルモジュールのコンパイルはここでは行わないようにしよう。

# cd /root
# tar xvzf vtune91u5_target.tar.gz
# cd vtune91u5_target
# ./install-vtune-sep.sh

 もしカーネルモジュールに必要なツールが不足している場合、適宜yumコマンドでインストールする。また、chroot環境にインストールされているカーネルヘッダーのバージョンと、ホスト側のカーネルバージョンは一致している必要がある。もし異なっている場合は、適宜必要なカーネルヘッダー等をインストールしておこう。

# yum install <インストールするパッケージ>

 カーネルモジュールのコンパイルは、Intel VTune Performance Analyzer Sampling Collectorのインストールディレクトリ以下の「vdk/src」ディレクトリで行う。「build-driver」というコンパイル用スクリプトが用意されているので、これに適切な引数を与えて実行すれば良い。

# cd /opt/intel/vtune/vdk/src/
# ./build-driver --kernel-file=/boot/vmlinuz-2.6.31.6-17.1.moblin2-netbook --kernel-version=2.6.31.6-17.1.moblin2-netbook --system-map-file=/boot/System.map-2.6.31.6-17.1.moblin2-netbook --kernel-src-dir=/usr/src/kernels/2.6.31.6-17.1.moblin2-netbook/

 なお、上記の例ではカーネルのバージョンが「2.6.31.6-17.1.moblin2-netbook」の場合の例である。実際に試してみる場合は、カーネルのバージョンに合わせて引数を適宜変更してほしい。

 build-driverスクリプトを実行し、指示に従って設定を確認するとコンパイル作業が行われ、指定したカーネルに対応したカーネルモジュール(vtune_drv-x32-<カーネルバージョン>smp.ko)が作成される。chroot環境を終了し、作成したモジュールをリモートマシン環境にコピーしよう。

# exit
$ sudo umount proc
$ sudo umount dev
$ scp /opt/intel/vtune/vdk/src/vtune_drv*.ko root@<リモートマシンのIPアドレス>:/opt/intel/vtune/vdk/src/

 リモートマシン環境でカーネルモジュールをロードするには、Intel VTune Performance Analyzer Sampling Collectorに付属する「insmod-vtune」というスクリプトを実行すれば良い。

$ cd /opt/intel/vtune/vdk/src
$ sudo ./insmod-vtune

 最後に、「lsmod」コマンドを実行してロードされたモジュールを確認しておこう。コンパイルしたカーネルモジュールが正しくロードされていれば、「vtune_drv」というモジュールが表示されるはずだ。

$ lsmod
Module                  Size  Used by
vtune_drv             211432  0
uvcvideo               50788  0
battery                10012  0
rt2860sta             430588  0
eeepc_laptop           11724  0

サンプルデータの取得

 以上でサンプルデータを取得する準備は完了だ。続いて、実際にサンプルデータを取得してみよう。

 サンプルデータの取得は、「sep」コマンドで行う。詳細については付属ドキュメント(/opt/intel/vtune/doc以下に格納されている)を参照してほしいが、たとえばシステム全体に対して20秒間のサンプリングを行い、結果を/tmp/以下に「my_data」として保存するには次のようにする。

$ cd /tmp
$ /opt/intel/vtune/bin/sep -start -d 20 -out my_data

 サンプリングが完了すると、/tmp以下にサンプリングデータを格納したファイル(チューニングファイル)が保存される。たとえば上記のように実行した場合、「my_data.tb5」というファイルが作成される。サンプリング結果を参照・解析するにはこのファイルをホストに転送し、VTuneで開けば良い。

$ scp my_data.tb5 <ホストのIPアドレス>:

VTuneでサンプリング結果を解析する

 取得したサンプリングデータは、ホスト側でVTuneのGUIを使用して解析できる。VTuneのGUIは次のようにして起動できる。なお、ドキュメントにも記載されているが、VTuneはroot権限で起動する必要がある。root権限のない一般ユーザーでも起動はできるものの、解析機能を利用しようとすると「モジュールが読み込めない」といった旨のメッセージが表示されて正しく動作しないので注意してほしい。

$ sudo /opt/intel/atom/vtune/bin/vltec

 VTuneを起動したら、「File」メニューの「Import」を選択する。「Import」ウィザードが表示されるので、まず「Other」−「Tuning file」を選択して「Next」をクリックしよう(図9)。「Import a Tuning File」画面が表示されるので、読み込むチューニングファイルを選択して「Finish」をクリックしよう。

 すると、VTuneのメインウィンドウ左下にある「Tuning Browser」に読み込んだチューニングファイルが追加されるので、「Imported Sampling Results」をダブルクリックするとサンプリング結果が表示される(図10

 サンプリング結果には、サンプリング中に実行されていたすべてのプロセスに関する情報が含まれている。「Process」タブを選択するとプロセス一覧が表示されるので、ここで詳細情報を確認したいプロセスをダブルクリックすると、今度は「Thread」タブに切り替わり、そのプロセスが使用していたスレッドが表示される(図11)。

 VTuneによるサンプリング結果解析ではこのように「プロセス→スレッド→モジュール→ホットスポット」という順で確認したい情報を絞り込んでいく。最後の「ホットスポット」では、関数レベルでのサンプリング情報を確認できる。

 なお、ホットスポットの確認を行う際に対象となるモジュールのバイナリがローカルで見つからない場合、図12のようなメッセージボックスが表示される場合がある。この場合は、適宜対象となるバイナリを手動で指定すれば良い。

 また、VTuneではサンプリング中に実行されていたすべてのプロセスについて情報を取得できるが、ホットスポット情報を表示するには対象とするプロセスの実行ファイルにデバッグ情報が含まれている(つまり「-g」オプション付きでコンパイルされている)必要があるので注意したい。

 さて、図13はbzip2が使用する「libbz2.so.1.0.4」というモジュールのホットスポット情報を表示した例だ。ここから、「mainSort」という関数が最もCPU時間を消費していることが分かる。

 さらに、「mainSort」をダブルクリックすると該当するソースコードが表示され、ソースコード内の行レベルでどの処理がどれだけCPU時間を消費しているのかを確認できる(図14)。これで処理のボトルネックとなっている部分を見つけ出すことができるというわけだ。

クロス開発環境で非常に有用なインテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイート

 Moblinアプリケーション開発のようなクロス開発においては、開発を行うマシンと実際にアプリケーションを実行するマシンが異なるため、デバッグやパフォーマンス解析が難しかったり、手間がかかることが多い。しかし、インテル アプリケーション・デバッガーやVTuneでは、非常に簡単にデバッグやパフォーマンス解析が行える。ユーザーインターフェイスが貧弱なMIDや車載情報端末といったデバイスでは、これらを用いたリモートデバッグやリモートプロファイリングが特に有効である。これらの開発を行っているなら、インテル Atom プロセッサー向け インテル アプリケーション・ソフトウェア開発ツール・スイートはぜひ導入を検討すべき製品と言えるだろう。