プラットフォーム コードをデバッグする

Android Studio for Platform(ASfP)は、[デバッグ] ツール ウィンドウの [アタッチ] タブを中心に、多言語プラットフォームのデバッグを統合しています。

  • [Run] > [Attach to Android Process](Control+Alt+A)を選択して、 Java デバッガ、ネイティブ デバッガ(バンドルされた LLDB)、またはその両方を、実機または Cuttlefish 仮想 デバイスで 実行中のアプリまたはシステム プロセスにアタッチします。
  • アタッチする前に、読み込まれたすべての共有ライブラリ(.so)とその 8 文字の ELF ビルド ID を [ライブラリ] パネルで検査します。チェックマーク アイコンは、out/target/product/<device>/symbols の下にある一致するローカル デバッグ シンボルを検証します。
  • ツールバーからデバイスの前提条件を管理します。[システム プロセスを表示] でフィルタし、[Root Device] をクリックして adb root を実行します(有効な場合は [Device is rooted] が表示されます)。[Enable JDWP] をクリックして、userdebug ビルドで JDWP を有効にします。
  • 条件付きブレークポイントと例外ブレークポイントを設定し、エディタでインライン変数値を表示し、ドロップ フレームとスマート ステップインを使用し、実行時に構造化された C++ 型と Rust 型を検査します。

デバッガを使用する前に、ローカルの out/target/product/<device>/symbols/.build-id シンボル インデックスが存在するように lunch ターゲットをビルドし、一致するデバイス イメージをフラッシュまたは起動します。

Java と Java とネイティブのデュアル デバッグ

Java アプリケーション、Kotlin アプリケーション、システムアプリ(com.android.messaging、設定、SystemUI など)、または JNI と C++ コードまたは Rust コードを呼び出すプロセスをデバッグするには、次の手順を完了します。

  1. Java、Kotlin、C、C++、Rust のソースファイルにブレークポイントを設定する。
  2. [Run] > [Attach to Android Process](Control+Alt+A)を選択します。ASfP は、デバッグ ツール ウィンドウ内に固定された [アタッチ] タブを開きます。
  3. デバイスのプルダウン メニューから対象デバイスを選択します。userdebug ビルドで JDWP が有効になっていない場合は、[Enable JDWP] をクリックします。ASfP が persist.debug.dalvik.vm.jdwp.enabled=1 を設定し、デバイスを再起動します。有効にすると、ボタンに [JDWP enabled] と表示され、右クリックすると [Disable JDWP] アクションが表示されます。
  4. テーブルからターゲット プロセスを選択します(Java プロセスと ART プロセスにはコーヒー カップ アイコンが表示されます)。
  5. [Attach] タブの下部で、[Java debugger]、[Native debugger]、またはその両方を選択します。両方を選択すると、[Debug] ツール ウィンドウに 2 つのリンクされたタブ(組み込み LLDB の <process> (<pid>) と Java の <process> (<pid>)-jdwp)が開きます。ライフサイクルが関連付けられているため、どちらかのセッションを停止すると両方のセッションが停止します。
  6. [アタッチ] をクリックし、デバイス上のアプリを操作してブレークポイントに到達させます。

Java とネイティブのデバッグタブが [Attach] タブの横にリンクされている

システム プロセス(C および C++)のデバッグとシンボルの検証

システム デーモン、HAL、システム サービス(android.hardware.bluetooth-service.cuttlefish、surfaceflinger、audioserver など)をデバッグするには、次の手順を行います。

  1. [Run] > [Attach to Android Process](Control+Alt+A)を開きます。ツールバーに [Root Device] が表示されたら、それをクリックして ASfP で adb root を実行し、[Device is rooted] を表示します。
  2. 上部のツールバーで [システム プロセスを表示] を選択し、ターゲット プロセスをフィルタします。
  3. [ライブラリ] パネルでローカル デバッグ シンボルを確認する: プロセスを選択すると、プロセスに読み込まれたすべての ELF 共有ライブラリ(.so)と、その ELF ビルド ID の最初の 8 文字の 16 進数が [ライブラリ] テーブルに表示されます。ASfP は各ビルド ID を out/target/product/<device>/symbols と照合します(APEX 内のライブラリを解決するには symbols/.build-id が必要です)。
    • 検証済みのライブラリにはチェックマーク アイコンが表示されます。解決済みの行にカーソルを合わせると、完全なローカル .debug シンボルパスをプレビューできます。
    • 一致するローカル シンボルがない未解決のライブラリには、警告アイコンが表示されます。
  4. Java 以外のプロセスの検出: C++ または Rust のプロセス(六角形の C アイコンでマークされている)を選択すると、ASfP は [Java デバッガ] を非表示にし、[Java デバッグは利用できません。Java プロセスではありません。] を表示します。このとき、[ネイティブ デバッガ] はオンのままになります。
  5. C、C++、Rust のソースファイルにブレークポイントを設定し、[Attach] をクリックして、デバイスでコードパスをトリガーします。

[Attach] タブに、[Libraries] テーブル、[ELF Build IDs]、ローカル シンボルのチェックマークが表示されている

Rust コードをデバッグする

ASfP は、C と C++ に使用されるのと同じ組み込み LLDB デバッガを使用して Rust プラットフォーム コードをデバッグします。外部アダプタや手動サーバー設定は必要ありません。ASfP は、バンドルされたツールチェーンから lldb-dap を使用し、AOSP プリビルドから Rust プリティ プリンタを自動的に読み込むため、String、Vec、HashMap、Option などの標準タイプは [変数] ペインに構造化された値を表示します。

デバイスで実行中の Rust プロセスにアタッチする

システム プロセス(C および C++)のデバッグの手順に沿って、[Run] > [Attach to Android Process] を開き、[Device is rooted] を確認して、[Libraries] パネルにローカル シンボルがチェックマーク付きで表示されていることを確認し、[Native debugger] をオンのままにして、[Attach] をクリックします。Rust と C または C++ のスタック フレームが同じデバッグ セッションに一緒に表示されます。

rust_test モジュールまたは rust_test_host モジュールをデバッグする

  1. rust_test または rust_test_host ターゲットを宣言する Android.bp ファイルを開き、モジュール タイプの横にあるガターの [実行] アイコンをクリックします。
  2. [Debug '<ModuleName>'] を選択します。ASfP はターゲットをビルドし、ホストマシンまたは接続されたデバイスの LLDB でテスト バイナリを起動して、Rust ブレークポイントで一時停止します。
  3. 単一のテスト関数をデバッグしたり、LLDB 起動コマンドをカスタマイズしたりするには、 [実行] > [構成を編集] を開き、生成された Soong テスト 構成を選択して、[メソッド] を設定するか、[デバッガ] オプションを開きます。Soong Test 構成オプションの詳細については、atest でテスト プラットフォーム コードをテストするをご覧ください。

ASfP で構造化変数ビジュアライザーを使用して Rust プラットフォーム コードをデバッグする