Skip to content

Commit 239e863

Browse files
committed
tutorials: end-user, and python developer
1 parent 170c40f commit 239e863

6 files changed

+1106
-114
lines changed

README.md

+11-114
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
# BPF Compiler Collection (BCC)
33

44
BCC is a toolkit for creating efficient kernel tracing and manipulation
5-
programs, and includes several useful tools and examples. It makes use of eBPF
6-
(Extended Berkeley Packet Filters), a new feature that was first added to
7-
Linux 3.15. Much of what BCC uses requires Linux 4.1 and above.
5+
programs, and includes several useful tools and examples. It makes use of
6+
extended BPF (Berkeley Packet Filters), formally known as eBPF, a new feature
7+
that was first added to Linux 3.15. Much of what BCC uses requires Linux 4.1
8+
and above.
89

910
eBPF was [described by](https://lkml.org/lkml/2015/4/14/232) Ingo Molnár as:
1011

1112
> One of the more interesting features in this cycle is the ability to attach eBPF programs (user-defined, sandboxed bytecode executed by the kernel) to kprobes. This allows user-defined instrumentation on a live kernel image that can never crash, hang or interfere with the kernel negatively.
1213
13-
BCC makes eBPF programs easier to write, with kernel instrumentation in C
14-
and a front-end in Python. It is suited for many tasks, including performance
15-
analysis and network traffic control.
14+
BCC makes BPF programs easier to write, with kernel instrumentation in C
15+
(and includes a C wrapper around LLVM), and front-ends in Python and lua.
16+
It is suited for many tasks, including performance analysis and network
17+
traffic control.
1618

1719
## Screenshot
1820

@@ -170,46 +172,10 @@ The features of this toolkit include:
170172
In the future, more bindings besides python will likely be supported. Feel free
171173
to add support for the language of your choice and send a pull request!
172174

173-
## Tutorial
175+
## Tutorials
174176

175-
The BCC toolchain is currently composed of two parts: a C wrapper around LLVM,
176-
and a Python API to interact with the running program. Later, we will go into
177-
more detail of how this all works.
178-
179-
### Hello, World
180-
181-
First, we should include the BPF class from the bpf module:
182-
```python
183-
from bcc import BPF
184-
```
185-
186-
Since the C code is so short, we will embed it inside the python script.
187-
188-
The BPF program always takes at least one argument, which is a pointer to the
189-
context for this type of program. Different program types have different calling
190-
conventions, but for this one we don't care so `void *` is fine.
191-
```python
192-
BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()
193-
```
194-
195-
For this example, we will call the program every time `fork()` is called by a
196-
userspace process. Underneath the hood, fork translates to the `clone` syscall.
197-
BCC recognizes prefix `kprobe__`, and will auto attach our program to the kernel symbol `sys_clone`.
198-
199-
The python process will then print the trace printk circular buffer until ctrl-c
200-
is pressed. The BPF program is removed from the kernel when the userspace
201-
process that loaded it closes the fd (or exits).
202-
203-
Output:
204-
```
205-
bcc/examples$ sudo python hello_world.py
206-
python-7282 [002] d... 3757.488508: : Hello, World!
207-
```
208-
209-
For an explanation of the meaning of the printed fields, see the trace_pipe
210-
section of the [kernel ftrace doc](https://www.kernel.org/doc/Documentation/trace/ftrace.txt).
211-
212-
[Source code listing](examples/hello_world.py)
177+
- [docs/tutorial.md](docs/tutorial.md): Using bcc tools to solve performance, troubleshooting, and networking issues.
178+
- [docs/tutorial_bcc_python_developer.md](docs/tutorial_bcc_python_developer.md): Developing new bcc programs using the Python interface.
213179

214180
### Networking
215181

@@ -222,75 +188,6 @@ multiple granularities. See the code [here](examples/networking/tunnel_monitor).
222188

223189
[![Screenshot](http://img.youtube.com/vi/yYy3Cwce02k/0.jpg)](https://youtu.be/yYy3Cwce02k)
224190

225-
### Tracing
226-
227-
Here is a slightly more complex tracing example than Hello World. This program
228-
will be invoked for every task change in the kernel, and record in a BPF map
229-
the new and old pids.
230-
231-
The C program below introduces two new concepts.
232-
The first is the macro `BPF_TABLE`. This defines a table (type="hash"), with key
233-
type `key_t` and leaf type `u64` (a single counter). The table name is `stats`,
234-
containing 1024 entries maximum. One can `lookup`, `lookup_or_init`, `update`,
235-
and `delete` entries from the table.
236-
The second concept is the prev argument. This argument is treated specially by
237-
the BCC frontend, such that accesses to this variable are read from the saved
238-
context that is passed by the kprobe infrastructure. The prototype of the args
239-
starting from position 1 should match the prototype of the kernel function being
240-
kprobed. If done so, the program will have seamless access to the function
241-
parameters.
242-
```c
243-
#include <uapi/linux/ptrace.h>
244-
#include <linux/sched.h>
245-
246-
struct key_t {
247-
u32 prev_pid;
248-
u32 curr_pid;
249-
};
250-
// map_type, key_type, leaf_type, table_name, num_entry
251-
BPF_TABLE("hash", struct key_t, u64, stats, 1024);
252-
// attach to finish_task_switch in kernel/sched/core.c, which has the following
253-
// prototype:
254-
// struct rq *finish_task_switch(struct task_struct *prev)
255-
int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
256-
struct key_t key = {};
257-
u64 zero = 0, *val;
258-
259-
key.curr_pid = bpf_get_current_pid_tgid();
260-
key.prev_pid = prev->pid;
261-
262-
val = stats.lookup_or_init(&key, &zero);
263-
(*val)++;
264-
return 0;
265-
}
266-
```
267-
[Source code listing](examples/tracing/task_switch.c)
268-
269-
The userspace component loads the file shown above, and attaches it to the
270-
`finish_task_switch` kernel function.
271-
The [] operator of the BPF object gives access to each BPF_TABLE in the
272-
program, allowing pass-through access to the values residing in the kernel. Use
273-
the object as you would any other python dict object: read, update, and deletes
274-
are all allowed.
275-
```python
276-
from bcc import BPF
277-
from time import sleep
278-
279-
b = BPF(src_file="task_switch.c")
280-
b.attach_kprobe(event="finish_task_switch", fn_name="count_sched")
281-
282-
# generate many schedule events
283-
for i in range(0, 100): sleep(0.01)
284-
285-
for k, v in b["stats"].items():
286-
print("task_switch[%5d->%5d]=%u" % (k.prev_pid, k.curr_pid, v.value))
287-
```
288-
[Source code listing](examples/tracing/task_switch.py)
289-
290-
## Getting started
291-
292-
See [INSTALL.md](INSTALL.md) for installation steps on your platform.
293-
294191
## Contributing
295192

296193
Already pumped up to commit some code? Here are some resources to join the

0 commit comments

Comments
 (0)