Commit 4fd308f9 authored by Brenden Blanco's avatar Brenden Blanco

Support automatic kprobe event detection in common case

* In the simple case, a user only creates 1 C function to be used with
  kprobes. Detect this common case and don't require the user to repeat
  themselves by passing the fn_name to attach_kprobe().
  e.g.: BPF(text='int sys_clone(void *ctx) {/*do stuff*/}').trace_print()
Signed-off-by: default avatarBrenden Blanco <bblanco@plumgrid.com>
parent 8d0425cb
......@@ -8,6 +8,4 @@
from bcc import BPF
b = BPF(text='void hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); }')
b.attach_kprobe(event="sys_clone", fn_name="hello")
b.trace_print()
BPF(text='void sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); }').trace_print()
......@@ -38,6 +38,10 @@ lib.bpf_module_license.restype = ct.c_char_p
lib.bpf_module_license.argtypes = [ct.c_void_p]
lib.bpf_module_kern_version.restype = ct.c_uint
lib.bpf_module_kern_version.argtypes = [ct.c_void_p]
lib.bpf_num_functions.restype = ct.c_ulonglong
lib.bpf_num_functions.argtypes = [ct.c_void_p]
lib.bpf_function_name.restype = ct.c_char_p
lib.bpf_function_name.argtypes = [ct.c_void_p, ct.c_ulonglong]
lib.bpf_function_start.restype = ct.c_void_p
lib.bpf_function_start.argtypes = [ct.c_void_p, ct.c_char_p]
lib.bpf_function_size.restype = ct.c_size_t
......@@ -345,6 +349,12 @@ class BPF(object):
raise Exception("Failed to compile BPF module %s" % src_file)
def load_func(self, func_name, prog_type):
# empty func_name signifies auto-detection...works when only 1 fn exists
if not func_name:
if lib.bpf_num_functions(self.module) != 1:
raise Exception("Param func_name is None but num_functions > 1, ambiguous")
func_name = lib.bpf_function_name(self.module, 0).decode()
if func_name in self.funcs:
return self.funcs[func_name]
......@@ -578,9 +588,8 @@ class BPF(object):
exit()
return line
@staticmethod
def trace_print(fmt=None):
"""trace_print(fmt=None)
def trace_print(self, fmt=None):
"""trace_print(self, fmt=None)
Read from the kernel debug trace pipe and print on stdout.
If fmt is specified, apply as a format string to the output. See
......@@ -588,13 +597,19 @@ class BPF(object):
example: trace_print(fmt="pid {1}, msg = {5}")
"""
# Cater to one-liner case where attach_kprobe is omitted and C function
# name matches that of the kprobe.
if len(open_kprobes) == 0:
fn = self.load_func(None, BPF.KPROBE)
self.attach_kprobe(event=fn.name, fn_name=fn.name)
while True:
if fmt:
fields = BPF.trace_fields(nonblocking=False)
fields = self.trace_fields(nonblocking=False)
if not fields: continue
line = fmt.format(*fields)
else:
line = BPF.trace_readline(nonblocking=False)
line = self.trace_readline(nonblocking=False)
print(line)
sys.stdout.flush()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment