}
void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb, void *cb_cookie, int pid, int cpu) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
int pfd;
struct perf_event_attr attr = {};
struct perf_reader *reader = NULL;
if (!reader)
goto error;
- attr.config = PERF_COUNT_SW_BPF_OUTPUT;
+ attr.config = 10;//PERF_COUNT_SW_BPF_OUTPUT;
attr.type = PERF_TYPE_SOFTWARE;
attr.sample_type = PERF_SAMPLE_RAW;
attr.sample_period = 1;
attr.wakeup_events = 1;
pfd = syscall(__NR_perf_event_open, &attr, pid, cpu, -1, PERF_FLAG_FD_CLOEXEC);
if (pfd < 0) {
- perror("perf_event_open");
+ fprintf(stderr, "perf_event_open: %s\n", strerror(errno));
+ fprintf(stderr, " (check your kernel for PERF_COUNT_SW_BPF_OUTPUT support, 4.4 or newer)\n");
goto error;
}
perf_reader_set_fd(reader, pfd);
perf_reader_free(reader);
return NULL;
-#else
- fprintf(stderr, "PERF_COUNT_SW_BPF_OUTPUT feature unsupported\n");
- return NULL;
-#endif
}
from collections import MutableMapping
import ctypes as ct
+import multiprocessing
from .libbcc import lib, _RAW_CB_TYPE
raise Exception("Could not open perf buffer")
fd = lib.perf_reader_fd(reader)
self[self.Key(cpu)] = self.Leaf(fd)
- open_kprobes[(id(self), cpu)] = reader
+ self.bpf.open_kprobes()[(id(self), cpu)] = reader
# keep a refcnt
self._cbs[cpu] = fn
def close_perf_buffer(self, key):
- reader = open_kprobes.get((id(self), key))
+ reader = self.bpf.open_kprobes().get((id(self), key))
if reader:
lib.perf_reader_free(reader)
- del(open_kprobes[(id(self), key)])
+ del(self.bpf.open_kprobes()[(id(self), key)])
del self._cbs[key]
# Licensed under the Apache License, Version 2.0 (the "License")
from bcc import BPF
-from ctypes import c_int, c_ulonglong
+import ctypes as ct
import random
import time
from unittest import main, TestCase
def test_simple(self):
b = BPF(text="""BPF_TABLE("array", int, u64, table1, 128);""")
t1 = b["table1"]
- t1[c_int(0)] = c_ulonglong(100)
- t1[c_int(127)] = c_ulonglong(1000)
+ t1[ct.c_int(0)] = ct.c_ulonglong(100)
+ t1[ct.c_int(127)] = ct.c_ulonglong(1000)
for i, v in t1.items():
if i.value == 0:
self.assertEqual(v.value, 100)
def test_native_type(self):
b = BPF(text="""BPF_TABLE("array", int, u64, table1, 128);""")
t1 = b["table1"]
- t1[0] = c_ulonglong(100)
- t1[-2] = c_ulonglong(37)
- t1[127] = c_ulonglong(1000)
+ t1[0] = ct.c_ulonglong(100)
+ t1[-2] = ct.c_ulonglong(37)
+ t1[127] = ct.c_ulonglong(1000)
for i, v in t1.items():
if i.value == 0:
self.assertEqual(v.value, 100)
self.assertEqual(t1[-2].value, 37)
self.assertEqual(t1[-1].value, t1[127].value)
+ def test_perf_buffer(self):
+ self.counter = 0
+
+ class Data(ct.Structure):
+ _fields_ = [("ts", ct.c_ulonglong)]
+
+ def cb(cpu, data, size):
+ self.assertGreater(size, ct.sizeof(Data))
+ event = ct.cast(data, ct.POINTER(Data)).contents
+ self.counter += 1
+
+ text = """
+BPF_PERF_OUTPUT(events);
+int kprobe__sys_nanosleep(void *ctx) {
+ struct {
+ u64 ts;
+ } data = {bpf_ktime_get_ns()};
+ events.perf_submit(ctx, &data, sizeof(data));
+ return 0;
+}
+"""
+ b = BPF(text=text)
+ b["events"].open_perf_buffer(cb)
+ time.sleep(0.1)
+ b.kprobe_poll()
+ self.assertGreater(self.counter, 0)
+
if __name__ == "__main__":
main()