Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

GDB の使用

GNU プロジェクト デバッガ(GDB)は、一般的に使用される UNIX デバッガです。このページでは、プラットフォーム デベロッパー向けに、gdb を使用して Android アプリとプロセスをデバッグする方法の詳細を紹介します。サードパーティ アプリの開発については、アプリのデバッグをご覧ください。

前提条件

GDB を使用してアプリとプロセスをデバッグするための前提条件は次のとおりです。

  • envsetup.sh コマンドで環境を設定します。
  • lunch コマンドを実行します。

環境の設定の詳細については、環境を設定するをご覧ください。

実行中のアプリまたはプロセスをデバッグする

実行中のアプリまたはネイティブ デーモンに接続するには、PID を指定して gdbclient.py を使用します。たとえば、PID が 1234 のプロセスをデバッグするには、次のコマンドを実行します。

gdbclient.py -p 1234

このスクリプトはポート転送を設定して、デバイスで適切な gdbserver を起動し、ホストで適切な gdb を起動します。さらに、gdb を設定してシンボルを検出し、gdb をリモートの gdbserver に接続します。

ネイティブ プロセスの起動をデバッグする

起動時のプロセスをデバッグするには、gdbserver または gdbserver64 を使用します。64 ビットの実行可能ファイルの場合:

adb shell gdbserver64 :5039 /system/bin/MY_TEST_64_BIT_APP

32 ビットの実行可能ファイルの場合:

adb shell gdbserver :5039 /system/bin/MY_TEST_32_BIT_APP

出力例:

Process MY_TEST_64_BIT_APP created; pid = 3460
Listening on port 5039

次に、gdbserver 出力からアプリの PID を特定し、別のターミナル ウィンドウで使用します。

gdbclient.py -p APP_PID

最後に、gdb プロンプトで「continue」と入力します。

アプリの起動をデバッグする

起動時のアプリをデバッグすることが必要な場合があります。たとえば、クラッシュが発生したときに、コードをたどってクラッシュの前に何が起こったかを確認する場合です。アタッチが機能する場合もありますが、アタッチが可能になる前にアプリがクラッシュするためにアタッチできない場合もあります。logwrapper アプローチ(strace で使用)は、アプリにポートを開く権限がなく、gdbserver がその制限を継承する場合があるため、必ずしもうまくいくとは限りません。

アプリの起動をデバッグするには、設定アプリの開発者向けオプションを使用して、Java デバッガがアタッチされるのを待機するようアプリに指示します。

  1. 設定アプリ > [開発者向けオプション] > [デバッグアプリを選択] に移動し、リストからアプリを選択して、[デバッガを待機] をクリックします。
  2. アプリをランチャーから起動するか、コマンドラインを使用してアプリを実行します。
    adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
    
  3. アプリが読み込まれて、アプリがデバッガを待っていることを示すダイアログが表示されるまで待ちます。
  4. gdbservergdbclient を通常の方法でアタッチし、ブレークポイントを設定して処理を続行します。

アプリを実行可能にするため、Java Debugger(jdb)などの Java Debug Wire Protocol(JDWP)デバッガをアタッチします。

adb forward tcp:12345 jdwp:XXX  # (Where XXX is the PID
of the debugged process.)
jdb -attach localhost:12345

クラッシュしたアプリまたはプロセスをデバッグする

クラッシュしたプロセスを debuggerd で中断して gdb をアタッチする場合は、適切なプロパティを設定します。

  • Android 7.0 Nougat 以上
    
    adb shell setprop debug.debuggerd.wait_for_gdb true
    
  • Android 6.0 Marshmallow 以下
    adb shell setprop debug.db.uid 999999
    

debuggerd では、通常のクラッシュ出力の終わりに、次のコマンドを使用して gdb を接続する手順が表示されます。

gdbclient.py -p PID

シンボルなしのデバッグ

32 ビット ARM では、シンボルがないと、gdb はどの命令セットを逆アセンブルしているか(ARM か Thumb か)を判別できません。シンボル情報がないときにデフォルトとして選択される命令セットを指定するには、次のプロパティを設定します。

set arm fallback-mode arm  # or thumb

VS Code によるデバッグ

GDB は、Visual Studio Code でのプラットフォーム コードのデバッグをサポートしています。GDB の CLI インターフェースの代わりに VS Code のデバッガ フロントエンドを使用して、デバイスで実行されるネイティブ コードを制御、デバッグできます。

デバッグに VS Code を使用するには、その前に C/C++ 拡張機能をインストールしてください。

VS Code を使用してコードをデバッグするには:

  1. gdbclient.py の実行に必要なすべてのビルド アーティファクト(シンボルなど)が存在することを確認します。
  2. 次のコマンドを実行します。
    gdbclient.py -p pid | -n proc-name |
    -r ... --setup-forwarding vscode ANY_OTHER_FLAGS

    これにより JSON オブジェクトが出力され、gdbclient.py が引き続き実行されます。 これは想定どおりの動作です。gdbclient.py プログラムを強制終了しないでください。

  3. VS Code のデバッグタブで [add configuration] を選択し、次に [C/C++ gdb attach] を選択します。これにより、launch.json ファイルが開き、新しい JSON オブジェクトがリストに追加されます。
  4. 新しく追加されたデバッガ設定を削除します。
  5. gdbclient.py によって出力された JSON オブジェクトをコピーして、削除したオブジェクトに貼り付けます。変更を保存します。
  6. ウィンドウを再読み込みしてデバッガリストを更新するには、Ctrl+Shift+P キーを押して「reload window」と入力します。
  7. 新しいデバッガ設定を選択して、[run] をクリックします。10~30 秒後にデバッガが接続されます。
  8. デバッグが完了したら、gdbclient.py を実行中のターミナルに移動し、Enter キーを押して gdbclient.py プログラムを終了します。

デバッガ設定の初回セットアップが完了したら、その後はステップ 3~6 をスキップできます。