ndk-gdb

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

要件

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

  • ndk-build スクリプトを使用してアプリをビルドします。ndk-gdb スクリプトでは、以前の make APP=<name> メソッドを使ったビルドがサポートされていません。
  • android:debuggable 属性を true に設定する <application> 要素を含めることで、AndroidManifest.xml ファイルでのアプリのデバッグを有効にします。
  • 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 のマニュアルをご覧ください。

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

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

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

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

オプション

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

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

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

設定 説明
--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.