デバッガを使用する

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

GDB のサポートおよび提供は終了しました。GDB から LLDB に切り替える場合は、最初に LLDB チュートリアルをお読みいただくことをおすすめします。GDB の使用に慣れている方であれば、GDB から LLDB へのコマンドマップが移行時に非常に有用です。

前提条件

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

  • 通常の envsetup.sh コマンドを使用してビルド環境を設定します。
  • ビルド時に使用したのと同じ lunch コマンドを実行します。lunch 項目はデバッグ対象のデバイスと完全に一致する必要があります。 lunch 項目が接続デバイスと一致しないと、「You used the wrong lunch: TARGET_PRODUCT (aosp_arm64) does not match attached device (xyzabc)」という形式のエラーが表示されます。
  • デバイスをマシンに接続します。

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

バイナリのデバッグ

マシンで作成したバイナリをデバッグするには、バイナリをデバイスにコピーし、デバッガを起動する必要があります。次に例を示します。

adb push test.exe /data/local/tmp/test.exe
lldbclient.py --port 5038 -r /data/local/tmp/test.exe

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

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

lldbclient.py -p 1234

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

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

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

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

次に、デバッガのプロンプトに「continue」と入力します。

起動時のアプリのデバッグ

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

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

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

アプリを実行可能にするため、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 に「コピー&貼り付け」手順を提供します。この手順は、クラッシュしたプロセスにデバッガを接続する方法を示しています。

VS Code によるデバッグ

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

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

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

  1. lldbclient.py または lldbclient.py の実行に必要なすべてのビルド アーティファクト(シンボルなど)が存在することを確認します。
  2. VS Code で、コマンドを実行するために Ctrl+Shift+P キーを押し、[Debug: Add Configuration...] を検索して選択し、[LLDB] を選択します。これにより、launch.json ファイルが開き、新しい JSON オブジェクトがリストに追加されます。
  3. 追加されたデバッガ設定を、「// #lldbclient-generated-begin」と「// #lldbclient-generated-end」の 2 行のコメントで置き換えます。設定リストは、次のようになります。
    "configurations": [
        // #lldbclient-generated-begin
        // #lldbclient-generated-end
    ]

    上記のコメントは lldbclient.py で設定を書き込む場所を検出するために使用されます。リスト内に他の設定がある場合は、他の設定の後ろの最後に、このコメント行を追加します。

  4. envsetup.sh」と「lunch」を実行したターミナルで、下記のコマンドを実行します。
    lldbclient.py --setup-forwarding vscode-lldb \
          --vscode-launch-file LAUNCH_JSON_PATH \
          ANY_OTHER_FLAGS -p pid | -n proc-name | -r ...

    lldbclient.py により、生成された設定が launch.json が書き出されますが、プログラムの実行は継続します。これは想定どおりの動作です。lldbclient.py プログラムを強制終了しないでください。「--vscode-launch-file」を省略した場合、JSON スニペットが出力されるので、これをコピーして launch.json に貼り付けてください。

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

  5. [Run and Debug] サイドバーを開きます。デバッガリストに新しい設定が表示されます。F5 キーを押します(またはメニューから [Start Debugging] を選択します)。10~30 秒後にデバッガが接続されます。

    新しい設定が [Run and Debug] ビューに表示されない場合は、ウィンドウを再読み込みしてデバッガリストを更新するために、Ctrl+Shift+P キーを押し、「reload window」と入力します。

  6. デバッグが完了したら、lldbclient.py を実行しているターミナルに移動し、Enter キーを押して lldbclient.py プログラムを終了します。それ以降このスクリプトを実行すると、「#lldbclient-generated」から始まる 2 つのコメント行の間に設定が生成され、古い内容は置き換えられるため、手作業で削除する必要はありません。

生成済みの起動設定にカスタム プロパティを追加するには、--vscode-launch-props フラグを使用します。次の例のように使用します。

lldbclient.py --setup-forwarding vscode-lldb \
    --vscode-launch-props \
    '{"initCommands" : ["script print(\"Hello\")"], "preLaunchTask" : "Build"}' \
    ...
この例では、VS Code でデバッグの前に「Build」という名前のタスクを実行するプロパティと、スクリプトによって生成された手順に新しいデバッグ初期化手順を追加するプロパティを指定しています。使用できるプロパティの概要については、VS Code のドキュメントCodeLLDB 拡張機能のユーザー マニュアルを参照してください。