-
Notifications
You must be signed in to change notification settings - Fork 480
uftrace on Android
Currently uftrace is not running properly under Android.
Things that don't work -> Argument Tracing, Dynamic Tracing
This document provides a brief introduction to how uftrace can be built and run on Android.
Running uftrace on Android can be done in several ways (context).
-
chroot'ed(?) env. (eg. inside termux app)
- install uftrace package on Termux
- compile uftrace from source on Termux
-
system shell env. (ADB)
- run uftrace binary under chroot'ed env
- build uftace as NDK binary
-
AOSP 10 - Android Q
-
Google Pixel (aarch64)
- Android: aosp_sailfish-eng 10 (android-10.0.0_r1)
- Kernel: 3.18.137 (fixed to 3.18.x)
-
Virtual Device cuttlefish (x86)
- Android: aosp_cf_x86_phone (aosp_master@eef9850)
- Kernel: 5.4.6 (stock kernel. custom kernel available)
To compile AOSP, follow instruction under AOSP Document.
For sudo permission in adb shell, build AOSP with userdebug
or eng
variants.
If you're trying to test on cuttlefish Virtual Device, you don't have to compile it. Jump to Setting up Cuttlefish.
The stock kernel included in Android doesn't support with ftrace function tracer.
In order to use kernel tracing with uftrace, you should compile kernel with FUNCTION_TRACER option enabled.
- CONFIG_FUNCTION_TRACER=y
- CONFIG_DYNAMIC_FTRACE=y
Follow instruction for compiling AOSP kernel
For more information: AOSP Dynamic Ftrace
For every Android phone in the world, there are different procedures for installing AOSP (unlock phone) and there might be even impossible phones. So in this section will only briefly cover the concepts.
- Unlock your phone's bootloader : Search Here
- Get or build AOSP image
- Boot your device with fastboot : adb reboot fastboot
- Flash image to your phone with fastboot : fastboot flash
To find the proper way to prepare AOSP on your device, Google it.
- Build cuttlefish host tool (like emulator)
git clone https://github.com/google/android-cuttlefish
cd android-cuttlefish
sudo apt install build-essential devscripts debhelper
debuild -i -us -uc -b
sudo apt install cdbs config-package-dev
sudo apt-get install -f
sudo dpkg -i ../cuttlefish-common_*_amd64.deb
- Get cuttlefish AOSP image from Android CI
- From
aosp-master
branch, click aosp_cf_x86_phoneuserdebug
variant - At Artifacts tab, download below files
aosp_cf_x86_phone-img-xxxxxx.zip
cvd-host_package.tar.gz
- From
- Extract downloaded files
mkdir cf && cd cf
tar xvf /path/to/cvd-host_package.tar.gz
unzip /path/to/aosp_cf_x86_phone-img-xxxxxx.zip
- Run cuttlefish virtual machine
HOME=$PWD ./bin/launch_cvd
# To boot with custom compiled kernel, use -kernel-path option
# HOME=$PWD ./bin/launch_cvd -kernel_path /path/to/kernel/../x86/boot/bzImage
# If the graphic is slow, try below option
# HOME=$PWD ./bin/launch_cvd -gpu_mode=drm_virgl
- Connect cuttlefish with VNC
To view the screen, use VNC client (Tiger VNC) to access localhost 6444 port.
java -jar tightvnc-jviewer.jar -ScalingFactor=50 -Tunneling=no -host=localhost -port=6444
For more information: cuttlefish git
- Download Termux APK: F-droid Store
- Install APK with ADB
adb install com.termux*.apk
- Open termux app
There is already Uftrace Package in the Termux package repo.
pkg update
pkg install uftrace
uftrace --version
# uftrace v0.9.3 ( python tui perf sched dynamic )
For using latest feature of uftrace, compile inside termux.
Since termux doesn't have gcc
, use clang
instead. (gcc available with unofficial repo).
To meet the dependency requirements, install below packages.
pkg-config
libelf
python
capstone
libluajit
pkg update
pkg install git make clang
pkg install pkg-config libelf python capstone libluajit
./configure --prefix=$PREFIX
make -j 8
# WILL FAIL! Source code and LDFLAGS modification needed.
# libandroid-spawn, argp, shmem etc..
Since there is no libdw
package support from termux, separate compilation is required.
Unfortunately, elfutils
doesn't support compiling with clang. (It has to be done with some hacky way)
Refer to the following link to find out how to do it: libelf termux building
Thanks to contributor @gonapps, there's a demo for compiling and running uftrace on Android.
(The demo below is different from the environment in this document)
For custom compile, refer to Termux package build script:
https://github.com/termux/termux-packages/tree/master/packages/uftrace
From termux app, run uftrace.
uftrace --version
# uftrace v0.9.3 ( python tui perf sched dynamic )
From the Host side, elevate to root permission and execute uftrace under termux directory.
(su
is allowed only on AOSP phonedebug
, eng
variant.)
# From Host side, type:
adb shell
# Connect into android system shell
# vsoc_x86:/ $
whoami # shell
su
whoami # root
export PREFIX=/data/data/com.termux/files/usr
$PREFIX/bin/uftrace -L $PREFIX/lib --version
# uftrace v0.9.3 ( python tui perf sched dynamic )
Since termux environment doesn't have symbols for mcount
, compile with -pg
option will fail.
When compiling sources inside termux, compile with -lmcount
option.
# clang is binded to gcc
gcc -pg $PREFIX/uftrace/tests/s-abc.c
# ============= Result Truncated =============
# $PREFIX/bin/aarch64-linux-android-ld: $PREFIX/tmp/s-abc-833b6b.o: in function `c':
# s-abc.c:(.text+0xcc): undefined reference to `_mcount'
# clang-9: error: linker command failed with exit code 1 (use -v to see invocation)
gcc -pg -lmcount $PREFIX/uftrace/tests/s-abc.c
uftrace record a.out
uftrace replay
## DURATION TID FUNCTION
# [ 2163] | main() {
# [ 2163] | a() {
# [ 2163] | b() {
# 0.880 us [ 2163] | c();
# 3.475 us [ 2163] | } /* b */
# 4.448 us [ 2163] | } /* a */
# 5.631 us [ 2163] | } /* main */
Custom kernel with ftrace - function graph support is required!
(If no symbol name is shown, set kptr_restrict
value to 0.)
Termux environment doesn't support for root permission natively.
So in here, we'll running uftrace from system shell (ADB).
If you can get elevated permission inside (e.g. rooted phone) just try with su instead of ADB.
# 0. Prepare environment with ftrace - function graph supported kernel
# In here, I'll show how to boot custom kernel with Phone (Pixel 1, aarch64, sailfish, 3.18.xx)
# For booting custom kernel with cuttlefish, look [4. Run cuttlefish virtual machine] section.
adb reboot fastboot
fastboot boot Image.gz-dtb # Your own custom kernel image.
# 1. Before start tracing, compile s-mmap.c inside termux
gcc -pg -lmcount $PREFIX/uftrace/tests/s-mmap.c -o t-mmap
# 2. From Host side, type and connect into android system shell
adb shell # sailfish:/ $
su
whoami # root
# 3. Check current kernel supports ftrace - function graph.
cat /sys/kernel/debug/tracing/available_tracers
# blk function_graph function nop
# (optional) check kernel pointer restrict is set to 0.
cat /proc/sys/kernel/kptr_restrict
echo 0 > /proc/sys/kernel/kptr_restrict
# 4. Start Kernel trace inside Android
export PREFIX=/data/data/com.termux/files/usr
cd $PREFIX/../home/uftrace/tests
$PREFIX/bin/uftrace -L $PREFIX/lib record -K 10 t-mmap
# DURATION TID FUNCTION
# [ 3635] | main() {
# [ 3635] | foo() {
# [ 3635] | sys_openat() {
# [ 3635] | handle_IPI() {
# [ 3635] | irq_enter() {
# 1.719 us [ 3635] | rcu_irq_enter();
# 1.355 us [ 3635] | irqtime_account_irq();
...
There is currently no way to tracing the Android subsystem via uftrace. Instead, it is possible to tracing how Dalvikvm, one of Android's subsystems, works.
Try the following steps to trace dalvikvm:
- Get the Android Source Code
- Run the
lunch
and choose the host environment to compile.
$ lunch
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_mips-eng
4. aosp_mips64-eng
5. aosp_x86-eng
6. aosp_x86_64-eng
7. full_fugu-userdebug
8. aosp_fugu-userdebug
...
- Run the
m
and wait until done compiling. - Move
init.environ.rc
in the compiled output. It is located in the following path :out/target/product/generic_x86_64/root/init.environ.rc
. Find the path that matches your environment. - modify
init.environ.rc
like followed:
[ Original ]
# set up the global environment
on init
export ANDROID_BOOTLOGO 1
export ANDROID_ROOT /system
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
export ANDROID_STORAGE /storage
export EXTERNAL_STORAGE /sdcard
export ASEC_MOUNTPOINT /mnt/asec
export BOOTCLASSPATH /system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/legacy-test.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/apache-xml.jar:/system/framework/org.apache.http.legacy.boot.jar:/system/framework/android.hidl.base-V1.0-java.jar:/system/framework/android.hidl.manager-V1.0-java.jar
export SYSTEMSERVERCLASSPATH /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar
[ Modified ]
# set up the global environment
export ANDROID_BOOTLOGO=1
export ANDROID_ROOT=/system
export ANDROID_ASSETS=/system/app
export ANDROID_DATA=/data
export BOOTCLASSPATH=/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/legacy-test.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/s
ystem/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/apache-xml.jar:/system/framework/org.apache.http.legacy.boot.jar:/system/framework/android.hidl.base-V1.0-java.jar:/system/framework/android.hidl.manager-V1.0-java.jar
- apply it to your environment
$ source init.environ.rc
- run dalvikvm to see followed message
$ dalvikvm
dalvikvm F 02-18 20:47:17 11445 11445 utils.cc:761] Failed to find ANDROID_ROOT directory /system
Runtime aborting...
(Runtime does not yet exist!)
- copy
/system
from compiled output
$ sudo cp -R out/target/product/generic_x86_64/system /
now you can see different error message from dalvikvm.
$ dalvikvm
dalvikvm I 02-18 20:48:45 11477 11477 image_space.cc:270] RelocateImage: /system/bin/patchoat --input-image-location=/system/framework/boot.art --output-image-file= --instruction-set=x86_64 --base-offset-delta=-335872
dalvikvm F 02-18 20:48:45 11477 11477 utils.cc:761] Failed to find ANDROID_DATA directory /data
Runtime aborting...
-
make directory
/data
-
run uftrace with dalvikvm
$ uftrace record [email protected] dalvikvm -cp classes.zip HellWorld
finished it. just taste results!
$ uftrace info
# system information
# ==================
# program version : v0.8.2-1319-g52f6 ( dwarf python luajit tui perf sched dynamic )
# recorded on : Tue Feb 18 00:19:55 2020
# cmdline : uftrace record [email protected] dalvikvm -cp classes.zip HellWorld
# cpu info : AMD Ryzen 5 3600 6-Core Processor
# number of cpus : 12 / 12 (online / possible)
# memory info : 0.5 / 31.3 GB (free / total)
# system load : 0.10 / 0.11 / 0.09 (1 / 5 / 15 min)
# kernel version : Linux 5.0.0-23-generic
# hostname : ubuntu
# distro : "Ubuntu 18.04.3 LTS"
#
# process information
# ===================
# number of tasks : 6
# task list : 99798(dalvikvm64), 99802(dalvikvm64), 99803(dalvikvm64), 99804(dalvikvm64), 99805(dalvikvm64), 99806(dalvikvm64)
# exe image : /home/m/AOSP8/out/host/linux-x86/bin/dalvikvm64
# pattern : regex
# exit status : exited with code: 0
# elapsed time : 0.558800594 sec
# cpu time : 0.166 / 0.392 sec (sys / user)
# context switch : 35 / 1 (voluntary / involuntary)
# max rss : 35268 KB
# page fault : 61 / 40106 (major / minor)
# disk iops : 1256 / 8 (read / write)
Example demo recorded file: mmap_f-AOSP-kernel-aarch64.data.tar.xz
- Home
- Tutorial
- Development
- Practical Use Cases
- GCC
- Clang/LLVM
- Node.js
- Chromium
- MySQL/InnoDB
- FFmpeg
- CPython
- POCO
- Telegram
- yara
- RustPython
- cURL
- bpftrace
- SpiderMonkey
- Apache HTTP Server
- GStreamer
- Squid
- TCPDUMP
- OpenCV
- Libav
- Wireshark
- LXC
- Git
- Radare2
- uftrace on Android
- deno
- parallel sort algorithm
- LevelDB/RocksDB (YCSB)
- Redis
- libjpeg‐turbo (JPEG)
- JM (H.264/AVC)
- HM (HEVC)
- VTM (VVC)
- CUDA
- Erlang/OTP BEAM
- uftrace on Yocto
- TTCN3