Skip to content

Commit

Permalink
tutorial_bcc_python_developer: new way to get the event data (iovisor…
Browse files Browse the repository at this point in the history
…#2226)

Follow-up to iovisor#2198.
  • Loading branch information
boat0 authored and yonghong-song committed Feb 23, 2019
1 parent 5494328 commit eba6beb
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 19 deletions.
12 changes: 2 additions & 10 deletions docs/tutorial_bcc_python_developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ Code is [examples/tracing/hello_perf_output.py](../examples/tracing/hello_perf_o

```Python
from bcc import BPF
import ctypes as ct

# define BPF program
prog = """
Expand Down Expand Up @@ -281,21 +280,14 @@ int hello(struct pt_regs *ctx) {
b = BPF(text=prog)
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello")

# define output data structure in Python
TASK_COMM_LEN = 16 # linux/sched.h
class Data(ct.Structure):
_fields_ = [("pid", ct.c_uint),
("ts", ct.c_ulonglong),
("comm", ct.c_char * TASK_COMM_LEN)]

# header
print("%-18s %-16s %-6s %s" % ("TIME(s)", "COMM", "PID", "MESSAGE"))

# process event
start = 0
def print_event(cpu, data, size):
global start
event = ct.cast(data, ct.POINTER(Data)).contents
event = b["events"].event(data)
if start == 0:
start = event.ts
time_s = (float(event.ts - start)) / 1000000000
Expand All @@ -316,8 +308,8 @@ Things to learn:
1. ```bpf_get_current_pid_tgid()```: Returns the process ID in the lower 32 bits (kernel's view of the PID, which in user space is usually presented as the thread ID), and the thread group ID in the upper 32 bits (what user space often thinks of as the PID). By directly setting this to a u32, we discard the upper 32 bits. Should you be presenting the PID or the TGID? For a multi-threaded app, the TGID will be the same, so you need the PID to differentiate them, if that's what you want. It's also a question of expectations for the end user.
1. ```bpf_get_current_comm()```: Populates the first argument address with the current process name.
1. ```events.perf_submit()```: Submit the event for user space to read via a perf ring buffer.
1. ```class Data(ct.Structure)```: Now define the Python version of the C data structure.
1. ```def print_event()```: Define a Python function that will handle reading events from the ```events``` stream.
1. ```b["events"].event(data)```: Now get the event as a Python object.
1. ```b["events"].open_perf_buffer(print_event)```: Associate the Python ```print_event``` function with the ```events``` stream.
1. ```while 1: b.perf_buffer_poll()```: Block waiting for events.

Expand Down
10 changes: 1 addition & 9 deletions examples/tracing/hello_perf_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# This is a Hello World example that uses BPF_PERF_OUTPUT.

from bcc import BPF
import ctypes as ct

# define BPF program
prog = """
Expand Down Expand Up @@ -34,21 +33,14 @@
b = BPF(text=prog)
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello")

# define output data structure in Python
TASK_COMM_LEN = 16 # linux/sched.h
class Data(ct.Structure):
_fields_ = [("pid", ct.c_uint),
("ts", ct.c_ulonglong),
("comm", ct.c_char * TASK_COMM_LEN)]

# header
print("%-18s %-16s %-6s %s" % ("TIME(s)", "COMM", "PID", "MESSAGE"))

# process event
start = 0
def print_event(cpu, data, size):
global start
event = ct.cast(data, ct.POINTER(Data)).contents
event = b["events"].event(data)
if start == 0:
start = event.ts
time_s = (float(event.ts - start)) / 1000000000
Expand Down

0 comments on commit eba6beb

Please sign in to comment.