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 つのオプションを使用できるのは、Python バージョンの ndk-gdb のみです。

    スレッド サポート

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

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

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