Android* OS 上でのリモート・アプリケーション・デバッグ

同カテゴリーの次の記事

インテル® アーキテクチャー向けに Android* SDK をインストール

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Remote Application Debug on Android* OS」(http://software.intel.com/en-us/articles/application-debug-android/) の日本語参考訳です。


Android* OS アプリケーションのリモートデバッグ

Android* Debug Bridge

Android* Debug Bridge (ADB) は、ホスト上のデバッガー (通常は GDB または DDMS (Dalvik Debug Monitor Server) および ADT) とターゲットを実行している Android* イメージ間のデバッグ通信を制御するコマンドラインのツールです。ターゲットイメージはデバイス・エミュレーションまたは物理的な開発デバイス上で動作します。通信は USB-OTG (On-The-Go) または USB-イーサーネット・ドングル経由で行います。つまり、ADB は Android* 上でアプリケーションのデバッグを可能にするツールです。

さまざまなフォームファクターのデバイスを接続またはエミュレートすることが可能です。通常はスマートフォンまたはタブレットが対象ですが、 医療用タブレットや組込みデバイス、家庭用エネルギー管理システム、入庫管理システム、その他のインテリジェント・システム・アプリケーションを対象にすることもできます。

Android* Debug Bridge をセットアップしてインテル® Atom™ プロセッサー・ベースのプラットフォームをリモートデバッグすることは、ほかのアーキテクチャーをデバッグすることとほとんど違いはありません。

最初に、ADB を含む Android* SDK を開発ホストにインストールする必要があります。インストール方法は、http://developer.android.com/sdk/installing.html (英語) を参照してください。

ADB のセットアップ

ターゲットイメージが物理デバイス上で動作している場合、最初に USB-OTG または USB-イーサネットのサポートを追加します。USB-イーサネットをサポートするには、カーネル構成の変更とリビルドが必要です。必要に応じて、OEM から情報を入手してください。

リモート・アプリケーション・デバッグの標準的な手法は、Android* デバイスの既存の USB-OTG インターフェイスを使用することです。セットアップの詳細は、Android* 開発者 Web サイト (http://developer.android.com/guide/developing/device.html (英語)) を参照してください。

主要なステップを以下に示します。

  1. Android* のマニフェストでアプリケーションを「デバッグ可能」として宣言します。

    Eclipse* IDE から直接アプリケーションを実行する場合は、自動でデバッグが有効になるため、このステップをスキップできます。

    AndroidManifest.xml ファイルで、android:debuggable="true" 要素を追加します。

    注: マニフェスト・ファイルで手動でデバッグを有効にする場合は、必ずリリースビルドの前に無効にしてください (通常、アプリケーションのリリースバージョンはデバッグ可能ではありません)。

  2. デバイスの「USB デバッグ」を有効にします。

    デバイスで、[Settings (設定)] > [Applications (アプリケーション)] > [Development (開発)] を選択し、[USB debugging (USB デバッグ)] を有効にします (Android* 4.0 デバイスの場合は、[Settings (設定)] > [Developer options (デベロッパー・オプション)] で設定します)。

  3. システムをセットアップしてデバイスを検出します。

    • Windows* 上で開発している場合、ADB 用の USB ドライバーをインストールする必要があります。OEM ドライバーへのリンクとインストール・ガイドは、OEM USB Drivers のドキュメント (http://developer.android.com/sdk/oem-usb.html (英語)) を参照してください。
    • OS X* 上で開発している場合、そのままでも動作するためこのステップをスキップします。
    • Ubuntu* Linux* 上で開発している場合、開発に使用する各デバイスの USB 構成が記述された udev ルールファイルを追加する必要があります。各デバイスメーカー固有のベンダー ID を、ルールファイルの ATTR{idVendor} プロパティーに指定します。ベンダー ID のリストは、USB Vendor IDs (http://developer.android.com/guide/developing/device.html#VendorIds (英語)) を参照してください。Ubuntu* Linux* 上でデバイス検出をセットアップするには、次の操作を行います。

    root としてログインしてルールファイル (/etc/udev/rules.d/51-android.rules) を作成します。

    以下の形式でベンダーをファイルに追加します。
    SUBSYSTEM=="usb", ATTR{idVendor}=="", MODE="0666", GROUP="plugdev"

    注: 環境によっては、ルール構文が異なることがあります。必要に応じて、システムの udev ドキュメントを参照してください。ルール構文の概要は、「Writing udev rules」 (英語) を参照してください。

    次のコマンドを実行します。
    chmod a+r /etc/udev/rules.d/51-android.rules

    USB 経由で接続した場合、SDK の platform-tools/ ディレクトリーから adb devices コマンドを実行して、デバイスが接続されているかどうかを確認できます。デバイスが接続されていると、デバイス名がリストされます。

    CDK でブートされた Android* OS の場合、USB-OTG ケーブルを CDK のポート (USB ミニ B) と開発ホストのポート (USB A) に接続します。

    次のコマンドを実行すると接続されているデバイスが表示されます。

    $ adb devices
    * daemon not running.starting it now *
    * daemon started successfully *
    List of devices attached
    0123456789ABCDEF  device

    注: Linux* 開発ホストの接続に割り当てられたデバイス名を確認するには、dmesg コマンドで “usb-storage: device found at ” メッセージの番号を調べた後、”ls -l /dev/bus/usb/*” コマンドで番号を調べます。

Windows* 上の ADB

http://www.eclipse.org/downloads/ (英語) から Eclipse* Classic をダウンロードしてインストールします。  

http://developer.android.com/sdk/index.html (英語) から Windows* 用の Android* SDK パッケージ (android-sdk_r18-windows.zip または installer_r18-windows.exe) をダウンロードします。

Android* SDK をインストールすると、adb.exe が \android-sdk\platform-tools にインストールされます。

ADB ホストとクライアントの通信

ここまで、開発ホストへの ADB のインストールについて説明しました。ADB は 3 つのコンポーネントを含むクライアント/サーバー・プログラムです。

クライアントは、開発マシンで実行します。ADB コマンドを使用してシェルからクライアントを起動することができます。ADT プラグインや DDMS のようなほかの Android* ツールも、ADB クライアントを作成します。

開発マシンのバックグラウンド・プロセスとして実行されるサーバーは、 クライアントと (エミュレーターまたはデバイス上で実行する) ADB デーモン間の通信を管理します。

デーモンは、各エミュレーターまたはデバイスのインスタンスのバックグラウンド・プロセスとして実行されます。 

ADB クライアントを開始すると、クライアントはまず ADB サーバープロセスがすでに起動されているかどうかを確認します。起動していない場合、サーバープロセスを開始します。サーバーが開始すると、ローカルの TCP ポート 5037 をバインドして、ADB クライアントから送られるコマンドを監視します (すべての ADB クライアントはポート 5037 で ADB サーバーと通信します)。

次に、サーバーは実行中のすべてのエミュレーター/デバイスのインスタンスとの接続をセットアップします。サーバーは、5555 から 5585 の偶数番号のポート、およびエミュレーター/デバイスで使用されるポートをスキャンして、エミュレーター/デバイスのインスタンスを調べます。ADB デーモンが見つかると、そのポートへの接続をセットアップします。各エミュレーター/デバイスのインスタンスは連続するポートのペア (コンソール接続用の偶数番号のポートと ADB 接続用の奇数番号のポート) を利用することに注意してください。次に例を示します。

 エミュレーター 1、コンソール: 5554
 エミュレーター 1、adb: 5555
 エミュレーター 2、コンソール: 5556
 エミュレーター 2、adb: 5557 ...

ポート 5555 の ADB に接続されているエミュレーターのインスタンスは、コンソールがポート 5554 で監視するインスタンスと同じです。

すべてのエミュレーターのインスタンスへの接続がセットアップできれば、ADB コマンドを使用してインスタンスを制御およびアクセスできます。サーバーはエミュレーター/デバイスのインスタンスへの接続を管理して複数の ADB クライアントからのコマンドを処理するため、任意のクライアントから (またはスクリプトから) 任意のエミュレーター/デバイスのインスタンスを制御することができます。

ADB の起動

“adb shell” と入力します。接続に成功すると # プロンプトが表示されます。

$ adb shell

主な ADB デバイスのコマンド

以下のコマンドは、コマンドラインからターゲットデバイスまたはエミュレーションにデバッグ対象のアプリケーションを転送するのに役立ちます。特に、ssh ターミナル接続が利用できないときに便利です。

adb push <ローカル> <リモート> – ファイル/ディレクトリーをデバイスにコピーします。
adb pull <リモート> [<ローカル>] – デバイスからファイル/ディレクトリーをコピーします。
adb sync [ <ディレクトリー> ] – 変更された場合のみホストからデバイスにコピーします。
  (-l はリストのみでコピーしません)
  (詳細は ‘adb help all’ を参照)
adb shell – リモートシェルをインタラクティブに実行します。
adb shell <コマンド> – リモートシェルのコマンドを実行します。
adb emu <コマンド> – エミュレーター・コンソールのコマンドを実行します。
adb logcat [ <フィルター> ] – デバイスのログを表示します。
adb forward <ローカル> <リモート> – ソケット接続をフォワードします。 > は、次のいずれかを指定します。
  localabstract:
  localreserved:
  localfilesystem:
  dev:<デバイス名>
  jdwp:<プロセス pid> (リモートのみ)
adb jdwp – JDWP トランスポートをホストするプロセスの pid を表示します。
adb install [-l] [-r] [-s] – パッケージファイルをデバイスにプッシュしてインストールします。
  (‘-l’ はアプリケーションをフォワードロックします)
  (‘-r’ はアプリケーションを再インストールしてデータを保持します)
  (‘-s’ は内部ストレージの代わりに SD カードにインストールします)
adb uninstall [-k] <パッケージ> – パッケージをデバイスから削除します。
  (‘-k’ はデータとキャッシュのディレクトリーを保持します)

ADB のセットアップと使用法の詳細は、
http://developer.android.com/guide/developing/tools/adb.html (英語) を参照してください。

GDB (GNU* プロジェクト・デバッガー) での C/C++ ネイティブコードのデバッグ

GDB でデバッグする場合、デバッグ通信の制御にはデバイス上で実行する gdbserver が使用されますが、gdbserver が TCP/IP プロトコル経由で開発ホストの GDB と通信する通信トランスポート・レイヤーの制御には ADB の USB-イーサーネット・ドングル・ドライバーが使用されます。

gdbclient は、デバッグ通信環境をセットアップして、デバッグ対象のデバイス上で gdbserver を起動します。

使用法: gdbclient EXECUTABLE :PORT [PROG_PATH]
EXECUTABLE  実行形式の名前 (デフォルトは app_process)
PORT  接続ポート (デフォルトは 1234)
PROG_PATH   ターゲットの実行形式のフルパス (例えば /system/bin/mediaserver)

PROG_PATH が設定されている場合、gdclient は gdbserver を起動して PROG_PATH にアタッチします。

gdbserver を明示的に起動するには、次のコマンドを使用します。

# gdbserver :1234 --attach 269
Attached; pid = 269
Listening on port 1234

以下の詳細なデバッグセッション起動手順は、デバッグに (ADT や DDMS ではなく) GDB を使用する場合でも ADT がどのようにデバッグ通信に関係するかを示しています。ポート 1234 が使用されていると仮定します。

プロセスを起動します。

gdbserver :1234 /system/bin/executable

または既存のプロセスにアタッチします。

gdbserver :1234 --attach pid

ワークステーションで、adb を使用してポート 1234 をデバイスにフォワードします。

adb forward tcp:1234 tcp:1234

ソースツリーの “prebuilt” 領域に含まれる特別なバージョンの gdb を開始します。

prebuilt/Linux/toolchain-eabi-4.x.x/bin/i686-android-linux-gdb (Linux* の場合)
prebuilt/darwin-x86/toolchain-eabi-4.x.x/bin/i686-android-linux-gdb (Darwin の場合)

上記の GDB バージョンが見つからない場合は、ソースツリーで find prebuilt –name i686-android-linux-gdbin を実行して最新バージョンを検索します。

プライマリー・ディレクトリーの実行形式にはシンボル情報が含まれていないため、プライマリー・ディレクトリーではなく、シンボル・ディレクトリーの実行形式のコピーを使用していることを確認してください。

GDB で、ロードする共有ライブラリーの場所を指定します。

set solib-absolute-prefix /absolute-source-path/out/target/product/product-name/symbols
set solib-search-path /absolute-source-path/out/target/product/product-name/symbols/system/lib

absolute-source-path は、ソースツリーへのパスです。

正しいディレクトリーを指定していることを確認してください。誤ったディレクトリーを指定しても GDB は何も表示しません。

GDB コマンドを実行してデバイスに接続します。

(gdb) target remote :1234

:1234 は、ADB でデバイスにブリッジ接続されている、ローカルホストのポート 1234 に接続するように GDB に指示します。

これで、以前と同じ方法で、GDB を使用して Android* 上で実行しているネイティブ C/C++ コードのデバッグを開始できます。

詳細は、GDB (GNU* プロジェクト・デバッガー) のドキュメントを参照してください。

Eclipse* 用 ADT プラグインを使用する Android* アプリケーションのデバッグ

インテル® アーキテクチャー・ベースのデバイスのセットアップ・プロセスは、http://developer.android.com/sdk/eclipse-adt.html#installing (英語) に記述されている内容とほとんど変わりません。

ADT プラグインを使用すると、Eclipse* IDE からインテル® アーキテクチャー・ベースのエミュレーターとターゲットデバイス用のアプリケーションをデバッグできます。異なる機能セットによる 2 つの異なるデバッグ・パースペクティブを提供します。

必要に応じて機能セットを切り替えることができます。これらの機能セットは、アプリケーションのデバッグ時にそれぞれ異なるメリットがあります。

Eclipse* の Debug (デバッグ) パースペクティブ

Eclipse* の Debug (デバッグ) パースペクティブでは、以下のタブにアクセスできます。

Debug (デバッグ) – 以前および現在デバッグしている Android* アプリケーションと現在実行しているスレッドを表示します。

Variables (変数) – ブレークポイントがセットされると、コード実行中の変数値を表示します。

Breakpoints (ブレークポイント) – アプリケーション・コードにセットされているブレークポイントのリストを表示します。

LogCat – システムのログメッセージをリアルタイムに表示します。LogCat タブは DDMS パースペクティブでも利用できます。

Debug (デバッグ) パースペクティブにアクセスするには、[Window (ウィンドウ)] – [Open Perspective (パースペクティブを開く)] – [Debug (デバッグ)] をクリックします。詳細は、Eclipse* デバッガーのドキュメントを参照してください。

DDMS (Dalvik Debug Monitor Server) パースペクティブ

Eclipse* の DDMS パースペクティブでは、Eclipse* IDE から DDMS のすべての機能にアクセスできます。以下の DDMS セクションが利用できます。

Devices (デバイス) – ADB に接続されているデバイスおよび AVD のリストを表示します。

Emulator Control (エミュレーター制御) – デバイスの機能を実行します。

LogCat – システムのログメッセージをリアルタイムに表示します。

Threads (スレッド) – VM 内で現在実行しているスレッドを表示します。

Heap (ヒープ) – VM のヒープ使用状況を表示します。

Allocation Tracker (アロケーション・トラッカー) – オブジェクトのメモリー割り当てを表示します。

File Explorer (ファイル・エクスプローラー) – デバイスのファイルシステムの内容を表示します。

デバッグのアプリケーション・ランタイム環境

インテル® アーキテクチャー・ベースのデバイスをターゲットとする Android* アプリケーションのデバッグで異なるのは、デバッグするターゲットデバイスの指定方法です。

Android* SDK の一部である Android* Virtual Device Manager を使用してターゲットデバイスを選択し、Eclipse* IDE のプルダウンメニューで [Window (ウィンドウ)] > [AVD Manager (AVD マネージャー)] を選択します。OS イメージおよびデバイス・エミュレーションの EABI ターゲットとして “Intel Atom” を選択していることを確認します。

avd_intel.jpg

ADB のセットアップの手順に従って物理デバイスへのデバッグブリッジを確立している場合、Eclipse* IDE でアプリケーション配置およびデバッグのターゲットとしてデバイスを選択できます。

device_chooser.jpg

ほかの点では、インテル® アーキテクチャーをターゲットとする Android* アプリケーションのデバッグは、ARM* アーキテクチャーをターゲットとする場合と違いはありません。 

http://developer.android.com/guide/developing/debugging/index.html (英語) に記載されている内容がすべて適用されます。

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事