Fix bcc_resolve_symname memory leak in C++ API
authorTeng Qin <qinteng@fb.com>
Sun, 21 May 2017 05:11:30 +0000 (22:11 -0700)
committerTeng Qin <qinteng@fb.com>
Sun, 21 May 2017 05:40:38 +0000 (22:40 -0700)
src/cc/BPF.cc
src/cc/BPF.h

index 98febc4f295463ab287aa2a000677c098c26e355..74577ffadb585a48980c07fdcf4f9cd8d7693203 100644 (file)
@@ -184,11 +184,11 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
                                bpf_probe_attach_type attach_type,
                                pid_t pid, int cpu, int group_fd,
                                perf_reader_cb cb, void* cb_cookie) {
-  bcc_symbol sym = bcc_symbol();
-  TRY2(check_binary_symbol(binary_path, symbol, symbol_addr, &sym));
+  std::string module;
+  uint64_t offset;
+  TRY2(check_binary_symbol(binary_path, symbol, symbol_addr, module, offset));
 
-  std::string probe_event =
-      get_uprobe_event(sym.module, sym.offset, attach_type);
+  std::string probe_event = get_uprobe_event(module, offset, attach_type);
   if (uprobes_.find(probe_event) != uprobes_.end())
     return StatusTuple(-1, "uprobe %s already attached", probe_event.c_str());
 
@@ -197,7 +197,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
 
   void* res =
       bpf_attach_uprobe(probe_fd, attach_type, probe_event.c_str(), binary_path.c_str(),
-                        sym.offset, pid, cpu, group_fd, cb, cb_cookie);
+                        offset, pid, cpu, group_fd, cb, cb_cookie);
 
   if (!res) {
     TRY2(unload_func(probe_func));
@@ -337,10 +337,11 @@ 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) {
-  bcc_symbol sym = bcc_symbol();
-  TRY2(check_binary_symbol(binary_path, symbol, symbol_addr, &sym));
+  std::string module;
+  uint64_t offset;
+  TRY2(check_binary_symbol(binary_path, symbol, symbol_addr, module, offset));
 
-  std::string event = get_uprobe_event(sym.module, sym.offset, attach_type);
+  std::string event = get_uprobe_event(module, offset, attach_type);
   auto it = uprobes_.find(event);
   if (it == uprobes_.end())
     return StatusTuple(-1, "No open %suprobe for binary %s symbol %s addr %lx",
@@ -468,14 +469,24 @@ StatusTuple BPF::unload_func(const std::string& func_name) {
 
 StatusTuple BPF::check_binary_symbol(const std::string& binary_path,
                                      const std::string& symbol,
-                                     uint64_t symbol_addr, bcc_symbol* output) {
-  // TODO: Fix output.module memory leak here
+                                     uint64_t symbol_addr,
+                                     std::string &module_res,
+                                     uint64_t &offset_res) {
+  bcc_symbol output;
   int res = bcc_resolve_symname(binary_path.c_str(), symbol.c_str(),
-                                symbol_addr, 0, nullptr, output);
+                                symbol_addr, -1, nullptr, &output);
   if (res < 0)
     return StatusTuple(
         -1, "Unable to find offset for binary %s symbol %s address %lx",
         binary_path.c_str(), symbol.c_str(), symbol_addr);
+
+  if (output.module) {
+    module_res = output.module;
+    ::free(const_cast<char*>(output.module));
+  } else {
+    module_res = "";
+  }
+  offset_res = output.offset;
   return StatusTuple(0);
 }
 
index 3da3c999df576051a3523cf8b5bdba6e8bff84ba..b9f298edb47a5e5b3528d9b6cafd692e6d97b0a7 100644 (file)
@@ -171,7 +171,9 @@ private:
 
   StatusTuple check_binary_symbol(const std::string& binary_path,
                                   const std::string& symbol,
-                                  uint64_t symbol_addr, bcc_symbol* output);
+                                  uint64_t symbol_addr,
+                                  std::string &module_res,
+                                  uint64_t &offset_res);
 
   std::unique_ptr<BPFModule> bpf_module_;