デバッガの使用

このページでは、OS 開発で LLDB または GDB を使用する方法について詳しく説明します。アプリ開発については、アプリのデバッグをご覧ください。(LLDB に基づいて)Android Studio GUI を使用する方法について説明しています。

GDB は非推奨となっており、まもなく削除されます。GDB から LLDB に切り替える場合は、最初に LLDB チュートリアルをお読みいただくことをおすすめします。GDB の使用に慣れている方であれば、GDB から LLDB へのコマンドマップが移行時に非常に有用です。

前提条件

デバッガを使用するには:

  • 通常の envsetup.sh コマンドを使用してビルド環境を設定します。
  • ビルド時に使用したのと同じ lunch コマンドを実行します。

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

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

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

gdbclient.py -p 1234

このスクリプトは、ポート転送を設定して、デバイスで適切なリモート デバッグスタブを起動し、ホスト上でデバッガを開始し、シンボルを検出するように構成して、リモート デバッグスタブにシンボルを接続します。

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

起動時のプロセスをデバッグするには、-r オプションを指定して gdbclient.py を使用します。たとえば、ls /bin をデバッグするには、ホストで次のコマンドを実行します。

gdbclient.py -r /system/bin/ls /bin

次に、デバッガのプロンプトに「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 で中断してデバッガをアタッチできるようにするには、適切なプロパティを設定します。

  • Android 11 より後
    adb shell setprop debug.debuggerd.wait_for_debugger true
    
  • Android 11 以前
    adb shell setprop debug.debuggerd.wait_for_gdb true
    
  • Android 6.0 Marshmallow 以前
    adb shell setprop debug.db.uid 999999
    

debuggerd は通常のクラッシュ出力の最後に、logcat に「コピー&貼り付け」手順を提供します。この手順は、クラッシュしたプロセスにデバッガを接続する方法を示しています。

シンボルなしのデバッグ

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

set arm fallback-mode arm  # or thumb

VS Code によるデバッグ

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

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

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

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

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

    ツールを使用したフラグの解析の仕組みにより、-r フラグには最後のフラグを指定する必要があります(存在する場合)。

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