1BCC (BPF compiler collection) for Android 2========================================= 3 4Introduction 5------------ 6BCC is a compiler and a toolkit, containing powerful kernel tracing tools that 7trace at the lowest levels, including adding hooks to functions in kernel space 8and user space to deeply understand system behavior while being low in 9overhead. [Here's a presentation with an 10overview](http://www.joelfernandes.org/resources/bcc-ospm.pdf) and visit [BCC's 11project page](https://github.com/iovisor/bcc) for the official BCC 12documentation. 13 14Quick Start 15----------- 16adeb is the primary vehicle for running BCC on Android. It supports 17preparing the target Android device with necessary kernel headers, cloning and 18building BCC on device, and other setup. Take a look a quick look at [adeb 19README](https://github.com/joelagnel/adeb/blob/master/README.md) so that 20you're familiar with what it is. 21 22To download a prebuilt filesystem with BCC already built/installed for an ARM64 23device, you can just run: 24``` 25adeb prepare --full 26``` 27 28This downloads the FS and also downloads prebuilt kernel headers after 29detecting your device's kernel version. Running BCC this way may cause a warning 30at startup since the headers may not be an *exact* match for your kernel's 31sublevel (only version and patchlevel are matched), however it works well in 32our testing and could be used, as long as you can tolerate the warning. 33 34If you would like to setup your own kernel headers and prevent the warning, 35you can point adeb to the kernel sources which will extract headers from there: 36``` 37adeb prepare --full --kernelsrc /path/to/kernel-source/ 38``` 39For targets other than ARM64, see the [Other Architectures 40section](https://github.com/joelagnel/adeb/blob/master/BCC.md#other-architectures-other-than-arm64) 41 42Now to run BCC, just start an adeb shell: `adeb shell`. This uses adb 43as the backend to start a shell into your adeb environment. Try running 44`opensnoop` or any of the other BCC tracers to confirm that the setup worked 45correctly. 46 47If building your own kernel, following are the kernel requirements: 48 49You need kernel 4.9 or newer. Anything less needs backports. Your kernel needs 50to be built with the following config options at the minimum: 51``` 52CONFIG_KPROBES=y 53CONFIG_KPROBE_EVENT=y 54CONFIG_BPF_SYSCALL=y 55``` 56Optionally, 57``` 58CONFIG_UPROBES=y 59CONFIG_UPROBE_EVENT=y 60``` 61Additionally, for the criticalsection BCC tracer to work, you need: 62``` 63CONFIG_DEBUG_PREEMPT=y 64CONFIG_PREEMPTIRQ_EVENTS=y 65``` 66 67Build BCC during adeb install (Optional) 68-------------------------------------------- 69If you would like the latest upstream BCC built and installed on your Android 70device, you can run: 71``` 72adeb prepare --build --bcc --kernelsrc /path/to/kernel-source/ 73``` 74NOTE: This is a slow process and can take a long time. Since it not only builds 75BCC but also installs all non-BCC debian packages onto the filesystem and configures them. 76 77Other Architectures (other than ARM64) 78----------------------- 79By default adeb assumes the target Android device is based on ARM64 80processor architecture. For other architectures, use the --arch option. For 81example for x86_64 architecture, run: 82``` 83adeb prepare --arch amd64 --build --bcc --kernelsrc /path/to/kernel-source/ 84``` 85Note: The --download option ignores the --arch flag. This is because we only 86provide pre-built filesystems for ARM64 at the moment. 87Note: If you pass --arch, you have to pass --build, because prebuilt 88filesystems are not available for non-arm64 devices. 89 90Common Issues 91------------- 92Here are some common issues you may face when running different BCC tools. 93 94* Issue 1: Headers are missing on the target device. 95 96Symptom: This will usually result in an error like the following: 97``` 98root@localhost:/# criticalstat 99 100In file included from <built-in>:2 101In file included from /virtual/include/bcc/bpf.h:12: 102In file included from include/linux/types.h:5: 103include/uapi/linux/types.h:4:10: fatal error: 'asm/types.h' file not found 104 105#include <asm/types.h> 106 107 ^~~~~~~~~~~~~ 1081 error generated. 109Traceback (most recent call last): 110 111 File "./criticalstat.py", line 138, in <module> 112 b = BPF(text=bpf_text) 113 File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 297, in __init__ 114 raise Exception("Failed to compile BPF text:\n%s" % text) 115Exception: Failed to compile BPF text: 116 117#include <uapi/linux/ptrace.h> 118#include <uapi/linux/limits.h> 119#include <linux/sched.h> 120 121extern char _stext[]; 122``` 123 124* Issue 2: `CONFIG_KPROBES` isn't enabled. 125 126Symptom: This will result in an error like the following: 127``` 128Traceback (most recent call last): 129 File "/usr/share/bcc/tools/cachetop", line 263, in <module> 130 curses.wrapper(handle_loop, args) 131 File "/usr/lib/python2.7/curses/wrapper.py", line 43, in wrapper 132 return func(stdscr, *args, **kwds) 133 File "/usr/share/bcc/tools/cachetop", line 172, in handle_loop 134 b.attach_kprobe(event="add_to_page_cache_lru", fn_name="do_count") 135 File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 543, in 136attach_kprobe 137 fn = self.load_func(fn_name, BPF.KPROBE) 138 File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 355, in 139load_func 140 (func_name, errstr)) 141Exception: Failed to load BPF program do_count: Invalid argument 142``` 143 144* Issue 3: `CONFIG_BPF_SYSCALL` isn't enabled. 145 146Symptom: This may result in a compilation error like the following: 147``` 148root@localhost:/# cachetop 149Traceback (most recent call last): 150 File "/usr/share/bcc/tools/cachetop", line 263, in <module> 151 curses.wrapper(handle_loop, args) 152 File "/usr/lib/python2.7/curses/wrapper.py", line 43, in wrapper 153 return func(stdscr, *args, **kwds) 154 File "/usr/share/bcc/tools/cachetop", line 171, in handle_loop 155 b = BPF(text=bpf_text) 156 File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 297, in __init__ 157 raise Exception("Failed to compile BPF text:\n%s" % text) 158Exception: Failed to compile BPF text: 159 160 161 #include <uapi/linux/ptrace.h> 162 struct key_t { 163 u64 ip; 164 u32 pid; 165 u32 uid; 166 char comm[16]; 167 }; 168 169 BPF_HASH(counts, struct key_t); 170 171 int do_count(struct pt_regs *ctx) { 172 struct key_t key = {}; 173 u64 zero = 0 , *val; 174 u64 pid = bpf_get_current_pid_tgid(); 175 u32 uid = bpf_get_current_uid_gid(); 176 177 key.ip = PT_REGS_IP(ctx); 178 key.pid = pid & 0xFFFFFFFF; 179 key.uid = uid & 0xFFFFFFFF; 180 bpf_get_current_comm(&(key.comm), 16); 181 182 val = counts.lookup_or_init(&key, &zero); // update counter 183 (*val)++; 184 return 0; 185 } 186``` 187