From 9b04a6ffeb7f7d7ba1a1d7df56571e938b6e1190 Mon Sep 17 00:00:00 2001 From: Teng Qin Date: Sun, 31 Jul 2016 10:17:07 -0700 Subject: [PATCH] Fix tools still referencing ProcUtils (#625) Recent USDT change removed `procstat.py`, which the `argdist` and `trace` tools are still referencing. This diff moves the only method (`which`) they are using into the `BPF` class. Also, make `BPF.find_library` not to call `decode()` on `None`. --- src/python/bcc/__init__.py | 32 +++++++++++++++++++++++++++++++- tools/argdist.py | 2 +- tools/trace.py | 4 ++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index 7cb5fb8..e1469dc 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -118,6 +118,35 @@ class BPF(object): raise Exception("Could not find file %s" % filename) return filename + @staticmethod + def _find_exe(cls, bin_path): + """ + _find_exe(bin_path) + + Traverses the PATH environment variable, looking for the first + directory that contains an executable file named bin_path, and + returns the full path to that file, or None if no such file + can be found. This is meant to replace invocations of the + "which" shell utility, which doesn't have portable semantics + for skipping aliases. + """ + # Source: http://stackoverflow.com/a/377028 + def is_exe(fpath): + return os.path.isfile(fpath) and \ + os.access(fpath, os.X_OK) + + fpath, fname = os.path.split(bin_path) + if fpath: + if is_exe(bin_path): + return bin_path + else: + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + exe_file = os.path.join(path, bin_path) + if is_exe(exe_file): + return exe_file + return None + def __init__(self, src_file="", hdr_file="", text=None, cb=None, debug=0, cflags=[], usdt=None): """Create a a new BPF module with the given source code. @@ -487,7 +516,8 @@ class BPF(object): @staticmethod def find_library(libname): - return lib.bcc_procutils_which_so(libname.encode("ascii")).decode() + res = lib.bcc_procutils_which_so(libname.encode("ascii")) + return res if res is None else res.decode() def attach_tracepoint(self, tp="", fn_name="", pid=-1, cpu=0, group_fd=-1): """attach_tracepoint(tp="", fn_name="", pid=-1, cpu=0, group_fd=-1) diff --git a/tools/argdist.py b/tools/argdist.py index 36d0425..fa9276c 100755 --- a/tools/argdist.py +++ b/tools/argdist.py @@ -371,7 +371,7 @@ int PROBENAME(struct pt_regs *ctx SIGNATURE) def _attach_u(self): libpath = BPF.find_library(self.library) if libpath is None: - libpath = ProcUtils.which(self.library) + libpath = BPF._find_exe(self.library) if libpath is None or len(libpath) == 0: self._bail("unable to find library %s" % self.library) diff --git a/tools/trace.py b/tools/trace.py index 8fff394..d4b604b 100755 --- a/tools/trace.py +++ b/tools/trace.py @@ -9,7 +9,7 @@ # Licensed under the Apache License, Version 2.0 (the "License") # Copyright (C) 2016 Sasha Goldshtein. -from bcc import BPF, Tracepoint, Perf, ProcUtils, USDT +from bcc import BPF, Tracepoint, Perf, USDT from time import sleep, strftime import argparse import re @@ -416,7 +416,7 @@ BPF_PERF_OUTPUT(%s); libpath = BPF.find_library(self.library) if libpath is None: # This might be an executable (e.g. 'bash') - libpath = ProcUtils.which(self.library) + libpath = BPF._find_exe(self.library) if libpath is None or len(libpath) == 0: self._bail("unable to find library %s" % self.library) -- 2.7.4