From e48f7c9672770704014d5c3baee9f4a30e419670 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Fri, 28 Jul 2017 16:30:35 -0700 Subject: [PATCH] have uniform uprobe event names for python and C++ 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 --- src/cc/BPF.cc | 12 ++++++++---- src/cc/BPF.h | 5 +++-- src/python/bcc/__init__.py | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/cc/BPF.cc b/src/cc/BPF.cc index e1d6c6fa..0a6cb728 100644 --- a/src/cc/BPF.cc +++ b/src/cc/BPF.cc @@ -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; } diff --git a/src/cc/BPF.h b/src/cc/BPF.h index 1c659b18..4a4c46c2 100644 --- a/src/cc/BPF.h +++ b/src/cc/BPF.h @@ -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); diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index 73dab53a..7127f518 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -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]) -- 2.34.1