strace の使用

strace を使用すると、プロセスが行うシステム呼び出しと、そのシステム呼び出しが返す内容を確認できます。

strace の作成

strace を作成するには、次のコマンドを実行します。

    mmma -j6 external/strace
    

実行中のプロセスへのアタッチ

strace の非常に簡単かつ一般的な使用例は、次のようにして、実行中のプロセスにアタッチすることです。

    adb shell strace -f -p PID
    

-f フラグを指定すると、strace はプロセス内のすべてのスレッドと、後で生成される新しいスレッドにアタッチされます。

一般的なプロセスではシステム呼び出しが大量に発生するため、strace のマニュアル ページを参照し、実際に関心のあるデータのみを収集する方法について確認することをおすすめします。

アプリでの使用

アプリで strace を使用する手順は次のとおりです。

  1. strace を実行できるようにデバイスを設定します。ルート権限で SELinux を無効にし、ランタイムを再起動して、seccomp フィルタを削除する必要があります。削除しなかった場合、strace を実行できません。
        adb root
        adb shell setenforce 0
        adb shell stop
        adb shell start
        
  2. strace はアプリの uid の下で実行されるため、strace ログ用にグローバルに書き込み可能なディレクトリを設定します。
        adb shell mkdir -m 777 /data/local/tmp/strace
        
  3. トレースするプロセスを選択して起動します。
        adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
        
  4. プロセスを通常どおり起動します。

zygote での使用

zygote で strace を使用するには、関連する init.rc の zygote 行を修正します(adb shell setenforce 0 が必要)。

    cd system/core/
    patch -p1 <<EOF
    --- a/rootdir/init.zygote32.rc
    +++ b/rootdir/init.zygote32.rc
    @@ -1,4 +1,4 @@
    -service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    +service zygote /system/bin/strace -o /data/local/tmp/zygote.strace /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
         class main
         socket zygote stream 660 root system
         onrestart write /sys/android_power/request_state wake
    EOF
    

Android 起動時の strace ログの取得

Android 起動時に strace ログを取得するには、次のように変更します。

  • プロセス名が zygote から strace に変更されるため、strace の SELinux file_context がないことで、指定されたサービスを開始できない場合があります。対処するには、system/sepolicy/private/file_contexts に strace の新しい行を追加し、元のファイル コンテキストをコピーします。次に例を示します。
        /dev/socket/zygote      u:object_r:zygote_socket:s0
        + /system/bin/strace u:object_r:zygote_socket:s0
        
  • カーネル コマンドを追加し、SELinux permissive モードでデバイスを起動します。これを行うには、androidboot.selinux=permissiveBOARD_KERNEL_CMDLINE に追加します(この変数は、build/core/Makefile では読み取り専用になりますが、/device/*/BoardConfig の下では常に使用できます)。

    /device/google/marlin/sailfish/BoardConfig.mk の Pixel(sailfish)デバイスの例を次に示します。
        - BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...
        +BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...  androidboot.selinux=permissive
        
    変更後、ブートイメージをビルドしてフラッシュすると、デバイスが permissive モードで起動します。