strace を使用すると、プロセスが行うシステムコールと、そのシステムコールが返す結果を確認できます。
strace の作成
strace を作成するには、次のコマンドを実行します。
mmma -j6 external/strace
実行中のプロセスにアタッチする
strace の非常に簡単かつ一般的な使用例は、次のように、実行中のプロセスにアタッチすることです。
adb shell strace -f -p PID
-f
フラグを指定すると、strace はプロセス内のすべてのスレッドと、後で生成される新しいスレッドにアタッチされます。
一般的なプロセスでは大量のシステムコールが行われるため、strace のマニュアル ページを参照して、実際に必要なデータのみを収集する方法を確認することをおすすめします。
アプリで使用する
アプリで strace を使用する手順は次のとおりです。
- strace を実行できるようにデバイスをセットアップします。root 権限で SELinux を無効にし、ランタイムを再起動して、seccomp フィルタを削除する必要があります。削除しないと、strace を実行できません。
adb root
adb shell setenforce 0
adb shell stop
adb shell start
- strace はアプリの uid で実行されるため、strace ログ用に、グローバルに書き込み可能なディレクトリを設定します。
adb shell mkdir -m 777 /data/local/tmp/strace
- トレースするプロセスを選択して起動します。
adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
- プロセスを通常どおり起動します。
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
の SELinuxfile_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
- カーネルまたは bootconfig のパラメータを追加し、SELinux の permissive モードでデバイスを起動します。これを行うには、
androidboot.selinux=permissive
をBOARD_KERNEL_CMDLINE
に追加するか、カーネル バージョン 5.10 以降の Android 12 ではBOARD_BOOTCONFIG
に追加します。(この変数は、build/core/Makefile
では読み取り専用ですが、/device/*/BoardConfig
の下では常に使用可能です)。
/device/google/marlin/sailfish/BoardConfig.mk
の Google Pixel(sailfish)デバイスの例を次に示します。 変更後、ブートイメージをビルドしてフラッシュすると、デバイスが permissive モードで起動します。- BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... +BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... androidboot.selinux=permissive