Commit e84febdf authored by Sasha Goldshtein's avatar Sasha Goldshtein

bcc: Make regex helpers publicly accessible

Make the `get_user_functions`, `get_kprobe_functions`, and
`get_tracepoints` methods publicly accessible from the BPF class.
These can then be used by tools that need to do their own work
before attaching programs to a set of functions or tracepoints.
parent b778ccd9
...@@ -376,7 +376,8 @@ class BPF(object): ...@@ -376,7 +376,8 @@ class BPF(object):
% (dev, errstr)) % (dev, errstr))
fn.sock = sock fn.sock = sock
def _get_kprobe_functions(self, event_re): @staticmethod
def get_kprobe_functions(event_re):
with open("%s/../kprobes/blacklist" % TRACEFS) as blacklist_file: with open("%s/../kprobes/blacklist" % TRACEFS) as blacklist_file:
blacklist = set([line.rstrip().split()[1] for line in blacklist = set([line.rstrip().split()[1] for line in
blacklist_file]) blacklist_file])
...@@ -386,7 +387,6 @@ class BPF(object): ...@@ -386,7 +387,6 @@ class BPF(object):
fn = line.rstrip().split()[0] fn = line.rstrip().split()[0]
if re.match(event_re, fn) and fn not in blacklist: if re.match(event_re, fn) and fn not in blacklist:
fns.append(fn) fns.append(fn)
self._check_probe_quota(len(fns))
return fns return fns
def _check_probe_quota(self, num_new_probes): def _check_probe_quota(self, num_new_probes):
...@@ -409,7 +409,7 @@ class BPF(object): ...@@ -409,7 +409,7 @@ class BPF(object):
# allow the caller to glob multiple functions together # allow the caller to glob multiple functions together
if event_re: if event_re:
for line in self._get_kprobe_functions(event_re): for line in BPF.get_kprobe_functions(event_re):
try: try:
self.attach_kprobe(event=line, fn_name=fn_name, pid=pid, self.attach_kprobe(event=line, fn_name=fn_name, pid=pid,
cpu=cpu, group_fd=group_fd) cpu=cpu, group_fd=group_fd)
...@@ -448,7 +448,7 @@ class BPF(object): ...@@ -448,7 +448,7 @@ class BPF(object):
# allow the caller to glob multiple functions together # allow the caller to glob multiple functions together
if event_re: if event_re:
for line in self._get_kprobe_functions(event_re): for line in BPF.get_kprobe_functions(event_re):
try: try:
self.attach_kretprobe(event=line, fn_name=fn_name, pid=pid, self.attach_kretprobe(event=line, fn_name=fn_name, pid=pid,
cpu=cpu, group_fd=group_fd) cpu=cpu, group_fd=group_fd)
...@@ -531,7 +531,8 @@ class BPF(object): ...@@ -531,7 +531,8 @@ class BPF(object):
res = lib.bcc_procutils_which_so(libname.encode("ascii")) res = lib.bcc_procutils_which_so(libname.encode("ascii"))
return res if res is None else res.decode() return res if res is None else res.decode()
def _get_tracepoints(self, tp_re): @staticmethod
def get_tracepoints(tp_re):
results = [] results = []
events_dir = os.path.join(TRACEFS, "events") events_dir = os.path.join(TRACEFS, "events")
for category in os.listdir(events_dir): for category in os.listdir(events_dir):
...@@ -570,7 +571,7 @@ class BPF(object): ...@@ -570,7 +571,7 @@ class BPF(object):
""" """
if tp_re: if tp_re:
for tp in self._get_tracepoints(tp_re): for tp in BPF.get_tracepoints(tp_re):
self.attach_tracepoint(tp=tp, fn_name=fn_name, pid=pid, self.attach_tracepoint(tp=tp, fn_name=fn_name, pid=pid,
cpu=cpu, group_fd=group_fd) cpu=cpu, group_fd=group_fd)
return return
...@@ -615,7 +616,13 @@ class BPF(object): ...@@ -615,7 +616,13 @@ class BPF(object):
del self.open_uprobes[name] del self.open_uprobes[name]
_num_open_probes -= 1 _num_open_probes -= 1
def _get_user_functions(self, name, sym_re): @staticmethod
def get_user_functions(name, sym_re):
return set([name for (name, _) in
BPF.get_user_functions_and_addresses(name, sym_re)])
@staticmethod
def get_user_addresses(name, sym_re):
""" """
We are returning addresses here instead of symbol names because it We are returning addresses here instead of symbol names because it
turns out that the same name may appear multiple times with different turns out that the same name may appear multiple times with different
...@@ -624,10 +631,15 @@ class BPF(object): ...@@ -624,10 +631,15 @@ class BPF(object):
it makes sense to return the unique set of addresses that are mapped to it makes sense to return the unique set of addresses that are mapped to
a symbol that matches the provided regular expression. a symbol that matches the provided regular expression.
""" """
return set([address for (_, address) in
BPF.get_user_functions_and_addresses(name, sym_re)])
@staticmethod
def get_user_functions_and_addresses(name, sym_re):
addresses = [] addresses = []
def sym_cb(sym_name, addr): def sym_cb(sym_name, addr):
if re.match(sym_re, sym_name) and addr not in addresses: if re.match(sym_re, sym_name):
addresses.append(addr) addresses.append((sym_name, addr))
return 0 return 0
res = lib.bcc_foreach_symbol(name, _SYM_CB_TYPE(sym_cb)) res = lib.bcc_foreach_symbol(name, _SYM_CB_TYPE(sym_cb))
...@@ -660,7 +672,7 @@ class BPF(object): ...@@ -660,7 +672,7 @@ class BPF(object):
name = str(name) name = str(name)
if sym_re: if sym_re:
for sym_addr in self._get_user_functions(name, sym_re): for sym_addr in BPF.get_user_adddresses(name, sym_re):
self.attach_uprobe(name=name, addr=sym_addr, self.attach_uprobe(name=name, addr=sym_addr,
fn_name=fn_name, pid=pid, cpu=cpu, fn_name=fn_name, pid=pid, cpu=cpu,
group_fd=group_fd) group_fd=group_fd)
...@@ -711,7 +723,7 @@ class BPF(object): ...@@ -711,7 +723,7 @@ class BPF(object):
""" """
if sym_re: if sym_re:
for sym_addr in self._get_user_functions(name, sym_re): for sym_addr in BPF.get_user_addresses(name, sym_re):
self.attach_uretprobe(name=name, addr=sym_addr, self.attach_uretprobe(name=name, addr=sym_addr,
fn_name=fn_name, pid=pid, cpu=cpu, fn_name=fn_name, pid=pid, cpu=cpu,
group_fd=group_fd) group_fd=group_fd)
......
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