ndk-gdb

NDK には、NDK で生成したマシンコードのネイティブ デバッグ セッションを簡単に起動するための ndk-gdb という名前のヘルパー シェル スクリプトが含まれています。

要件

ネイティブ デバッグを実行する場合は、次の要件を順守する必要があります。

  • 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 つまたは複数の)エクストラ フラグです。 同じコマンドでこのオプションの複数のインスタンスを使用することができます。

    --stdcxx-py-pr={auto|none|gnustdcxx[-GCCVER]|stlport}

    標準 C++ ライブラリの型を表示するために、指定された Python プリティプリンターを使用します。auto モードは、libstdc++ ライブラリの .so ファイルを検索することにより機能するため、共有ライブラリに対してのみ有効です。 libstdc++ ライブラリに静的にリンクするときに、必要なプリンターを指定する必要があります。 デフォルトは none です。

    注: この表の最後の 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.