ndk-gdb

NDK には、コマンドラインのネイティブ デバッグ セッションを開始するための ndk-gdb というシェル スクリプトが含まれています。GUI を使用するユーザーは、代わりに Android Studio でのデバッグに関するドキュメントをご覧になるようおすすめします。

要件

コマンドラインのネイティブ デバッグを使用するには、次の要件を満たす必要があります。

  • アプリを ndk-build スクリプトを使用してビルドすること。ndk-gdb スクリプトでは、以前の make APP=<name> メソッドを使ったビルドがサポートされていません。
  • AndroidManifest.xml ファイルでのアプリのデバッグを有効にする際、android:debuggable 属性を true に設定する <application> 要素を含めること。
  • Android 2.2(Android API レベル 8)以上で実行するアプリをビルドすること。
  • Android 2.2 以上を稼働するデバイスまたはエミュレータでデバッグすること。 デバッグは AndroidManifest.xml ファイルで宣言するターゲット API レベルにかかわりなく行われます。
  • アプリを Unix シェルで開発すること。Windows では、Cygwin を使用するか、Python 実装の ndk-gdb-py(試験運用版)を使用します。
  • GNU Make 3.81 以上を使用すること。

用途

アプリのディレクトリまたはその下のディレクトリに移動して、ndk-gdb スクリプトを呼び出します。次に例を示します。

cd $PROJECT
$NDK/ndk-gdb

ここで、$PROJECT はプロジェクトのルート ディレクトリを指し、$NDK は NDK のインストール パスを指します。

ndk-gdb を呼び出すと、ソースファイルと、生成されたネイティブ ライブラリのシンボル / デバッグ バージョンを検索するセッションが設定されます。アプリのプロセスに正常にアタッチすると、連続する長いエラー メッセージが ndk-gdb から出力され、さまざまなシステム ライブラリが見つからないことを警告します。ホストマシンには対象デバイスのシステム ライブラリのシンボル / デバッグ バージョンが含まれないため、これは正常な動作です。こうしたメッセージは無視してかまいません。

次に、ndk-gdb により通常の GDB プロンプトが表示されます。

GNU GDB と同じ方法で ndk-gdb を操作します。たとえば、b <location> を使用してブレークポイントを設定し、c(「続行」)を使用して実行を再開します。全コマンドの一覧については、GDB のマニュアルをご覧ください。LLDB デバッガを使用する場合は、ndk-gdb スクリプトを呼び出すときに --lldb オプションを使用します。

GDB プロンプトを終了すると、デバッグしているアプリケーション プロセスが停止することに注意してください。この動作は、gdb の制限事項です。

ndk-gdb は多くのエラー条件を処理し、問題を発見するとその情報を伝えるエラー メッセージを表示します。こうしたチェックでは、次の条件を満たすかどうかも確認されます。

  • ADB がパスにある。
  • マニフェストでアプリケーションがデバッグ可能であると宣言されている。
  • デバイス上の同じパッケージ名を持つインストール済みのアプリもデバッグ可能である。

デフォルトで、ndk-gdb によりすでに実行中のアプリのプロセスが検索され、見つからない場合はエラーが表示されます。ただし、--start オプションまたは --launch=<name> オプションを使用すると、デバッグ セッションの前にアクティビティを自動的に開始できます。詳細については、オプションの説明をご覧ください。

オプション

すべてのオプションのリストを表示するには、コマンドラインで「ndk-gdb --help」と入力します。表 1 に一般的に使用されるいくつかのオプションとその簡単な説明を示します。

表 1. 一般的な ndk-gdb オプションとその説明

このオプションを指定して ndk-gdb を開始すると、アプリのマニフェストにある最初の起動可能なアクティビティが起動します。次の起動可能なアクティビティを開始するには、--launch=<name> を使用します。起動可能なアクティビティのリストを出力するには、コマンドラインから --launch-list を実行します。

設定 説明
--lldb

設定すると、このスクリプトは gdb の代わりに LLDB デバッガをセッションに使用します。

--verbose

このオプションは、ネイティブ デバッグ セッションの設定に関する詳細情報を出力するようにビルドシステムに通知します。このオプションを使用する必要があるのは、デバッグに問題がある場合のみです(デバッガがアプリに接続できない、ndk-gdb が表示するエラー メッセージが十分でないなど)。

--force デフォルトで(このオプションを指定しない場合)、同じデバイスで別のネイティブ デバッグ セッションがすでに実行されていれば、ndk-gdb は中止されます。このオプションは他のセッションを強制終了して、新しいセッションに置き換えます。 このオプションを指定しても、デバッグ中のアプリは強制終了されないことにご注意ください。デバッグ中のアプリは別途強制終了する必要があります。
--start

デフォルトで、ndk-gdb は起動時に対象デバイスですでに実行されているアプリのインスタンスへのアタッチを試みます。--start を指定すると、デバッグ セッションの前に対象デバイスでアプリを明示的に起動することにより、このデフォルトの動作をオーバーライドできます。

--launch=<name>

このオプションは、アプリから特定のアクティビティを開始できることを除いては、--start と同じです。マニフェストで起動可能なアクティビティを複数定義している場合にのみ、この機能は有用です。

--launch-list

この便利なオプションは、アプリ マニフェストにあるすべての起動可能なアクティビティ名のリストを出力します。--start は最初のアクティビティ名を使用します。

--project=<path> このオプションは、アプリのプロジェクト ディレクトリを指定します。このオプションを使用すると、スクリプトを起動する前にプロジェクト ディレクトリに移動する必要がなくなるため便利です。
--port=<port>

デフォルトで、ndk-gdb はローカル TCP ポート 5039 を使用して対象デバイスでデバッグしているアプリと通信します。異なるポートを使用すると、異なるデバイスで実行されているプログラム、または同じホストマシンに接続しているエミュレータで実行されているプログラムをネイティブにデバッグできます。

--adb=<file>

このオプションは、adb ツールの実行可能ファイルを指定します。この実行可能ファイルのインクルード パスを設定していない場合にのみ、このオプションが必要です。

  • -d
  • -e
  • -s <serial>
  • これらのフラグは、同じ名前の adb コマンドと同様に機能します。複数のデバイスがある場合、またはホストマシンに接続しているエミュレータが複数ある場合は、これらのフラグを設定します。これらのフラグの意味は次のとおりです。

    -d
    単一の物理デバイスに接続します。
    -e
    単一のエミュレータ デバイスに接続します。
    -s <serial>
    特定のデバイスまたはエミュレータに接続します。ここで、<serial>adb devices コマンドで一覧表示されるデバイスの名前です。

    特定のオプションを使用せずに、ADB_SERIAL 環境変数を定義して特定のデバイスを表示することもできます。

  • --exec=<file>
  • -x <file>
  • このオプションは、デバッグ中のプロセスに接続した後、<file> で見つかった GDB 初期化コマンドを実行するよう ndk-gdb に指示します。この機能は、ブレークポイントのリストを設定してから実行を自動的に再開するなど、なんらかの操作を繰り返す場合に便利です。

    --nowait

    GDB が接続するまで Java コードを一時停止する機能を無効にします。このオプションを渡すと、デバッガが初期のブレークポイントを見落とすことがあります。

    --tui -t

    テキスト ユーザー インターフェースが利用できる場合は、そのインターフェースを有効にします。

    --gnumake-flag=<flag>

    このオプションは、プロジェクト情報をクエリするときに ndk-build システムに渡す(1 つまたは複数の)追加フラグです。同じコマンドにこのオプションの複数のインスタンスを指定できます。

    注: この表の最後の 3 つのオプションを使用できるのは、ndk-gdb の Python バージョンのみです。

    スレッド サポート

    Android 2.3(API レベル 9)より前のプラットフォームでアプリを実行している場合、ndk-gdb はネイティブ スレッドを適切にデバッグできません。デバッガはメインスレッドのみをデバッグ可能で、abd は他のスレッドの実行を完全に無視します。

    非メインスレッドで実行される関数にブレークポイントを設定すると、プログラムは終了し、GDB は次のメッセージを表示します。

    Program terminated with signal SIGTRAP, Trace/breakpoint trap.
          The program no longer exists.