# BCC & bpftrace - 安裝 主要的方法可以在 BCC 的 [INSTALL](https://github.com/iovisor/bcc/blob/master/INSTALL.md) 與 bpftrace 的 [INSTALL](https://github.com/iovisor/bpftrace/blob/master/INSTALL.md) 中找到。一般來說用 apt 安裝即可,但我自己使用 Ubuntu 19.10 時發現這似乎有點狀況,所以手動編譯了一次,而這篇主要是紀錄從自行編譯的過程。除此之外,BPF 需要啟動特定的核心組態(見兩者安裝文件),而且也要夠新版本的核心才有這個功能。但 Ubuntu 19.10 兩者都滿足,所以這部分的資訊就暫時省略。 ## 安裝 可以用 apt 安裝: ```shell= $ sudo apt-get install bpfcc-tools linux-headers-$(uname -r) $ sudo apt-get install bpftrace ``` 但如果跟我一樣使用 Ubuntu 19.10,那麼使用 `apt` 安裝後的 BCC (`bpfcc-tools`) 跟 `bpftrace` 可能會有問題。比如在執行 BCC repo 中的 `hello_world.py` 時可能會 segmentation fault; 或是執行書中可以正常執行的例子時,沒有預期的輸出,而是出現以下的訊息: ```shell $ bpftrace -e 'kprobe:vfs_*{@[probe] = count()}' Error creating map: '@': Invalid argument Error creating printf map: Invalid argument Creation of the required BPF maps has failed. Make sure you have all the required permissions and are not confined (e.g. like snapcraft does). `dmesg` will likely have useful output for further troubleshooting ``` 在我嘗試安裝時 (2020 年 1 月) ,這似乎是一個已知的 [bug](https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1709730.html)。`bpftrace` 的 repo 中也有相關的 [issue](https://github.com/iovisor/bpftrace/issues/1014) 。而其中一個解法是把 `bcc` 跟 `bpftrace` 通通自己編譯一遍,以下是編譯過程的記錄: ### BCC 以下資訊來自 BCC 的 [INSTALL](https://github.com/iovisor/bcc/blob/master/INSTALL.md#ubuntu---source) 中的指示。首先安裝指定的相依套件,以 Ubuntu 19.10 為例: ```shell= $ sudo apt install -y bison build-essential cmake flex git libedit-dev \ libllvm7 llvm-7-dev libclang-7-dev python zlib1g-dev libelf-dev ``` 如果不是 Ubuntu 19.10,在 BCC 的 INSTALL 中有對應的安裝指示。安裝完之後,把 BCC 的原始程式下載下來並編譯。相關的指令在 INSTALL 文件中可以找到: ```shell= git clone https://github.com/iovisor/bcc.git mkdir bcc/build; cd bcc/build cmake .. -DCMAKE_INSTALL_PREFIX=/usr make sudo make install ``` 如果想要用 python 3 的話,可以在 cmake 時多一個 `-DPYTHON_CMD=python3` flag。 ### bpftrace :::warning 以 Ubuntu 19.10 而言,如果 BCC 是用 `apt` 安裝 `bpfcc-tools` 而來,而不是自己編譯的話,那麼在編譯 `bpftrace` 時可能會出現以下的錯誤: ```cmake Workspace/bpftrace/src/ast/irbuilderbpf.cpp: In member function ‘void bpftrace::ast::IRBuilderBPF::CreateSignal(llvm::Value*)’: /home/f/Workspace/bpftrace/src/ast/irbuilderbpf.cpp:669:16: error: ‘BPF_FUNC_send_signal’ was not declared in this scope 669 | getInt64(BPF_FUNC_send_signal), | ^~~~~~~~~~~~~~~~~~~~ ``` 我的嘗試發現:如果 BCC 也自行編譯的話,就不會出現以上的錯誤。所以保險的作法可能是兩個都自己編譯。 ::: 或是自行編譯。而編譯的方法也很直接,照 `bpftrace` 的 repo 中的 [INSTALL](https://github.com/iovisor/bpftrace/blob/master/INSTALL.md#ubuntu) 指示: ```shell= sudo apt-get update sudo apt-get install -y bison cmake flex g++ git libelf-dev zlib1g-dev libfl-dev systemtap-sdt-dev binutils-dev sudo apt-get install -y llvm-7-dev llvm-7-runtime libclang-7-dev clang-7 git clone https://github.com/iovisor/bpftrace mkdir bpftrace/build; cd bpftrace/build; cmake -DCMAKE_BUILD_TYPE=Release .. make -j8 sudo make install ``` ## 簡單的測試 安裝完之後可以試試看使用: ```shell= $ sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' ``` 應該要出現下面這樣的輸出: ```shell= $ sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' Attaching 1 probe... ``` 按下 Ctrl + C 之後,應該會出現類似以下的輸出: ```shell= $ sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' Attaching 1 probe... ^C @[ssh-agent]: 2 @[sudo]: 3 @[gnome-software]: 4 @[WebExtensions]: 4 @[systemd-journal]: 4 @[update-notifier]: 4 @[gsd-keyboard]: 6 @[gsd-power]: 6 @[gsd-wacom]: 6 [...] ``` ## 附錄:環境 ### lscpu ``` Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 39 bits physical, 48 bits virtual CPU(s): 8 On-line CPU(s) list: 0-7 Thread(s) per core: 2 Core(s) per socket: 4 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 70 Model name: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz Stepping: 1 CPU MHz: 1292.163 CPU max MHz: 3700.0000 CPU min MHz: 800.0000 BogoMIPS: 4988.76 Virtualization: VT-x L1d cache: 128 KiB L1i cache: 128 KiB L2 cache: 1 MiB L3 cache: 6 MiB L4 cache: 128 MiB ``` ### uname ``` Linux f 5.3.0-26-generic #28-Ubuntu SMP x86_64 GNU/Linux ```