Remove asserts on str probe names
authorMark Drayton <mbd@fb.com>
Wed, 27 Jul 2016 02:08:20 +0000 (03:08 +0100)
committerMark Drayton <mbd@fb.com>
Wed, 27 Jul 2016 19:59:12 +0000 (20:59 +0100)
`open_kprobes` is a dict of open kprobes. Its keys are strings for normal
probes and a tuple for perf buffers. Normal probes need unregistering on script
exit; perf buffers do not. `cleanup` currently looks for string keys
(specifically type `str`) when working out what to unregister, which is a bit
brittle -- in Python2 strings can be both native `str` and `unicode`, depending
what exactly was passed to `attach-*/detach_*` and whether `from __future__
import unicode_literals` is used (e.g. #623).

This diff makes the API more relaxed by casting the probe name to `str` to
match the expectations of `cleanup`. This works in py2 (with and without
unicode_literals) and py3.

src/python/bcc/__init__.py

index ea85f79..6b4259e 100644 (file)
@@ -364,7 +364,6 @@ class BPF(object):
     def attach_kprobe(self, event="", fn_name="", event_re="",
             pid=-1, cpu=0, group_fd=-1):
 
-        assert isinstance(event, str), "event must be a string"
         # allow the caller to glob multiple functions together
         if event_re:
             for line in self._get_kprobe_functions(event_re):
@@ -375,6 +374,7 @@ class BPF(object):
                     pass
             return
 
+        event = str(event)
         self._check_probe_quota(1)
         fn = self.load_func(fn_name, BPF.KPROBE)
         ev_name = "p_" + event.replace("+", "_").replace(".", "_")
@@ -389,7 +389,7 @@ class BPF(object):
         return self
 
     def detach_kprobe(self, event):
-        assert isinstance(event, str), "event must be a string"
+        event = str(event)
         ev_name = "p_" + event.replace("+", "_").replace(".", "_")
         if ev_name not in self.open_kprobes:
             raise Exception("Kprobe %s is not attached" % event)
@@ -403,7 +403,6 @@ class BPF(object):
     def attach_kretprobe(self, event="", fn_name="", event_re="",
             pid=-1, cpu=0, group_fd=-1):
 
-        assert isinstance(event, str), "event must be a string"
         # allow the caller to glob multiple functions together
         if event_re:
             for line in self._get_kprobe_functions(event_re):
@@ -414,6 +413,7 @@ class BPF(object):
                     pass
             return
 
+        event = str(event)
         self._check_probe_quota(1)
         fn = self.load_func(fn_name, BPF.KPROBE)
         ev_name = "r_" + event.replace("+", "_").replace(".", "_")
@@ -428,7 +428,7 @@ class BPF(object):
         return self
 
     def detach_kretprobe(self, event):
-        assert isinstance(event, str), "event must be a string"
+        event = str(event)
         ev_name = "r_" + event.replace("+", "_").replace(".", "_")
         if ev_name not in self.open_kprobes:
             raise Exception("Kretprobe %s is not attached" % event)
@@ -527,6 +527,7 @@ class BPF(object):
                  BPF(text).attach_uprobe("/usr/bin/python", "main")
         """
 
+        name = str(name)
         (path, addr) = BPF._check_path_symbol(name, sym, addr)
 
         self._check_probe_quota(1)
@@ -549,6 +550,7 @@ class BPF(object):
         or binary 'name'.
         """
 
+        name = str(name)
         (path, addr) = BPF._check_path_symbol(name, sym, addr)
         ev_name = "p_%s_0x%x" % (self._probe_repl.sub("_", path), addr)
         if ev_name not in self.open_uprobes:
@@ -570,6 +572,7 @@ class BPF(object):
         meaning of additional parameters.
         """
 
+        name = str(name)
         (path, addr) = BPF._check_path_symbol(name, sym, addr)
 
         self._check_probe_quota(1)
@@ -592,6 +595,7 @@ class BPF(object):
         or binary 'name'.
         """
 
+        name = str(name)
         (path, addr) = BPF._check_path_symbol(name, sym, addr)
         ev_name = "r_%s_0x%x" % (self._probe_repl.sub("_", path), addr)
         if ev_name not in self.open_uprobes: