have uniform uprobe event names for python and C++
authorYonghong Song <yhs@fb.com>
Fri, 28 Jul 2017 23:30:35 +0000 (16:30 -0700)
committerBrenden Blanco <bblanco@gmail.com>
Wed, 16 Aug 2017 18:49:14 +0000 (11:49 -0700)
This is a followup change for previous commit 0ba15075fc5f
(permit multiple pids attaching to the same probe).
That commit changes the event name for python uprobe API
in order to permit multiple processes attaching to the
same uprobe point. The C++ uprobe event name remains
unchanged and thus a descrepancy.

This patch add changes to C++ side and also make python uretprobe
having the same naming convention.

Originally I experimented to put the common code to generate
event names in libbpf.c. But doing this seems more klunky
than simplicity of C++ and Python. So I stick to the current
design.

No need to add pid to kprobe event names as kprobe bpf invocation
will ignore pid anyway.

Signed-off-by: Yonghong Song <yhs@fb.com>
src/cc/BPF.cc
src/cc/BPF.h
src/python/bcc/__init__.py

index e1d6c6f..0a6cb72 100644 (file)
@@ -199,7 +199,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
   uint64_t offset;
   TRY2(check_binary_symbol(binary_path, symbol, symbol_addr, module, offset));
 
-  std::string probe_event = get_uprobe_event(module, offset, attach_type);
+  std::string probe_event = get_uprobe_event(module, offset, attach_type, pid);
   if (uprobes_.find(probe_event) != uprobes_.end())
     return StatusTuple(-1, "uprobe %s already attached", probe_event.c_str());
 
@@ -347,12 +347,13 @@ StatusTuple BPF::detach_kprobe(const std::string& kernel_func,
 
 StatusTuple BPF::detach_uprobe(const std::string& binary_path,
                                const std::string& symbol, uint64_t symbol_addr,
-                               bpf_probe_attach_type attach_type) {
+                               bpf_probe_attach_type attach_type,
+                               pid_t pid) {
   std::string module;
   uint64_t offset;
   TRY2(check_binary_symbol(binary_path, symbol, symbol_addr, module, offset));
 
-  std::string event = get_uprobe_event(module, offset, attach_type);
+  std::string event = get_uprobe_event(module, offset, attach_type, pid);
   auto it = uprobes_.find(event);
   if (it == uprobes_.end())
     return StatusTuple(-1, "No open %suprobe for binary %s symbol %s addr %lx",
@@ -551,10 +552,13 @@ BPFStackTable BPF::get_stack_table(const std::string& name,
 }
 
 std::string BPF::get_uprobe_event(const std::string& binary_path,
-                                  uint64_t offset, bpf_probe_attach_type type) {
+                                  uint64_t offset, bpf_probe_attach_type type,
+                                  pid_t pid) {
   std::string res = attach_type_prefix(type) + "_";
   res += sanitize_str(binary_path, &BPF::uprobe_path_validator);
   res += "_0x" + uint_to_hex(offset);
+  if (pid != -1)
+    res += "_" + std::to_string(pid);
   return res;
 }
 
index 1c659b1..4a4c46c 100644 (file)
@@ -72,7 +72,8 @@ public:
   StatusTuple detach_uprobe(
       const std::string& binary_path, const std::string& symbol,
       uint64_t symbol_addr = 0,
-      bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY);
+      bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY,
+      pid_t pid = -1);
   StatusTuple attach_usdt(const USDT& usdt, pid_t pid = -1, int cpu = 0,
                           int group_fd = -1);
   StatusTuple detach_usdt(const USDT& usdt);
@@ -142,7 +143,7 @@ private:
   std::string get_kprobe_event(const std::string& kernel_func,
                                bpf_probe_attach_type type);
   std::string get_uprobe_event(const std::string& binary_path, uint64_t offset,
-                               bpf_probe_attach_type type);
+                               bpf_probe_attach_type type, pid_t pid);
 
   StatusTuple detach_kprobe_event(const std::string& event, open_probe_t& attr);
   StatusTuple detach_uprobe_event(const std::string& event, open_probe_t& attr);
index 73dab53..7127f51 100644 (file)
@@ -878,7 +878,7 @@ class BPF(object):
 
         self._check_probe_quota(1)
         fn = self.load_func(fn_name, BPF.KPROBE)
-        ev_name = "r_%s_0x%x" % (self._probe_repl.sub("_", path), addr)
+        ev_name = self._get_uprobe_evname("r", path, addr, pid)
         res = lib.bpf_attach_uprobe(fn.fd, 1, ev_name.encode("ascii"),
                 path.encode("ascii"), addr, pid, cpu, group_fd,
                 self._reader_cb_impl, ct.cast(id(self), ct.py_object))
@@ -897,7 +897,7 @@ class BPF(object):
 
         name = str(name)
         (path, addr) = BPF._check_path_symbol(name, sym, addr, pid)
-        ev_name = "r_%s_0x%x" % (self._probe_repl.sub("_", path), addr)
+        ev_name = self._get_uprobe_evname("r", path, addr, pid)
         if ev_name not in self.open_uprobes:
             raise Exception("Uretprobe %s is not attached" % ev_name)
         lib.perf_reader_free(self.open_uprobes[ev_name])