Starting with Jelly Bean, perf is integrated in Android. If you download Google’s source tree you will find perf in external/linux-tools-perf
. This post explains what you need to do to use perf in the emulator.
Prerequisites
You need to download the latest Android tree from Google. For instructions on how to do this see How to build a custom Android emulator image.
You will also need the latest kernel version to use perf. perf will not work with kernel 2.6.29 since it does not have the CONFIG_HAVE_PERF_EVENTS option. The arm emulator does not work yet with kernel 3.4, so you will only be able to use perf with the x86 emulator for now. For instructions on how to use the emulator with the latest 3.4 kernel see Get the brand new 3.4 Android kernel working for the x86 emulator.
Once you have your Google tree and kernel compiled and the x86 emulator working, you can move on to the next steps.
Add needed kernel configuration options
One option you must enable in the kernel config is CONFIG_HAVE_PERF_EVENTS. By default this is enabled in the kernel. You can check your generated .config file to see if you have this option enabled:
$ cd ~/workspace/android/goldfish
$ cat .config | grep CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PERF_EVENTS=y
If you want to use kernel probes you must have CONFIG_KPROBES enabled. This is also enabled by default.
Unfortunately you cannot use user probes with the 3.4 kernel for the emulator. User probes have been integrated in the kernel starting with version 3.5.
If you want to get debug information from the kernel (and you probably do), you also have to enable CONFIG_DEBUG_INFO. You can do this by running make menuconfig
and selecting Kernel hacking -> Compile the kernel with debug info.
After you have set these kernel config options you need to recompile the kernel.
Missing kernel symbols
In order to trace and profile kernel functions you need to have the kernel image installed in a predefined path. perf will look for vmlinux in predefined paths like the current directory, /boot
and /lib/modules/3.4.0+/build
. The easiest way is to just copy vmlinux from our compiled kernel to /data
and run perf from there:
$ adb push vmlinux /data/
$ adb shell
# cd /data
Do not forget do go to /data
directory once you connect to the emulator through adb. Otherwise you will get this error:
# perf probe -a schedule Failed to find path of kernel module. Kernel symbol 'schedule' not found. Error: Failed to add events. (-2)
Show kernel pointers
By default /proc/sys/kernel/kptr_restrict is set to 2. If kptr_restrict is set to 2, kernel pointers are printed as 0’s regardless of privileges. We need to set kptr_restrict to 1 to allow printing kernel pointers for root:
# cat /proc/sys/kernel/kptr_restrict
2
# echo 1 > /proc/sys/kernel/kptr_restrict
# cat /proc/sys/kernel/kptr_restrict
1
Run perf
Now you can use perf in the emulator. For example, you can count the number of read system calls in one second:
# perf probe -a sys_read Add new event: probe:sys_read (on sys_read) You can now use it on all perf tools, such as: perf record -e probe:sys_read -aR sleep 1 # perf stat -e probe:sys_read -a sleep 1 Performance counter stats for 'sleep 1': 22 probe:sys_read 1.027680611 seconds time elapsed