def get_memory_maps(self): """Return process's mapped memory regions as a list of nameduples. Fields are explained in 'man proc'; here is an updated (Apr 2012) version: http://goo.gl/fmebo """ f = None try: f = open("/proc/%s/smaps" % self.pid) first_line = f.readline() current_block = [first_line] def get_blocks(): data = {} for line in f: fields = line.split(None, 5) if len(fields) >= 5: yield (current_block.pop(), data) current_block.append(line) else: data[fields[0]] = int(fields[1]) * 1024 yield (current_block.pop(), data) if first_line: # smaps file can be empty for header, data in get_blocks(): hfields = header.split(None, 5) try: addr, perms, offset, dev, inode, path = hfields except ValueError: addr, perms, offset, dev, inode, path = hfields + [''] if not path: path = '[anon]' else: path = path.strip() yield (addr, perms, path, data['Rss:'], data.get('Size:', 0), data.get('Pss:', 0), data.get('Shared_Clean:', 0), data.get('Shared_Dirty:', 0), data.get('Private_Clean:', 0), data.get('Private_Dirty:', 0), data.get('Referenced:', 0), data.get('Anonymous:', 0), data.get('Swap:', 0)) f.close() except EnvironmentError: # XXX - Can't use wrap_exceptions decorator as we're # returning a generator; this probably needs some # refactoring in order to avoid this code duplication. if f is not None: f.close() err = sys.exc_info()[1] if err.errno in (errno.ENOENT, errno.ESRCH): raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise except: if f is not None: f.close() raise f.close()
def get_process_exe(self): try: exe = os.readlink("/proc/%s/exe" % self.pid) except (OSError, IOError): err = sys.exc_info()[1] if err.errno == errno.ENOENT: # no such file error; might be raised also if the # path actually exists for system processes with # low pids (about 0-20) if os.path.lexists("/proc/%s/exe" % self.pid): return "" else: # ok, it is a process which has gone away raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise # readlink() might return paths containing null bytes causing # problems when used with other fs-related functions (os.*, # open(), ...) exe = exe.replace('\x00', '') # Certain names have ' (deleted)' appended. Usually this is # bogus as the file actually exists. Either way that's not # important as we don't want to discriminate executables which # have been deleted. if exe.endswith(" (deleted)") and not os.path.exists(exe): exe = exe[:-10] return exe
def wrapper(self, *args, **kwargs): try: return fun(self, *args, **kwargs) except OSError: err = sys.exc_info()[1] if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def wrapper(self, *args, **kwargs): try: return callable(self, *args, **kwargs) except EnvironmentError: # ENOENT (no such file or directory) gets raised on open(). # ESRCH (no such process) can get raised on read() if # process is gone in meantime. err = sys.exc_info()[1] if err.errno in (errno.ENOENT, errno.ESRCH): raise NoSuchProcess(self.pid, self._process_name) if err.errno in (errno.EPERM, errno.EACCES): raise AccessDenied(self.pid, self._process_name) raise
def __init__(self, *args, **kwargs): self.__subproc = subprocess.Popen(*args, **kwargs) self._pid = self.__subproc.pid self._gone = False self._ppid = None self._platform_impl = _psplatform.Process(self._pid) self._last_sys_cpu_times = None self._last_proc_cpu_times = None try: self.create_time except AccessDenied: pass except NoSuchProcess: raise NoSuchProcess(self._pid, None, "no process found with pid %s" % self._pid)
def __init__(self, pid): """Create a new Process object for the given pid. Raises NoSuchProcess if pid does not exist. Note that most of the methods of this class do not make sure the PID of the process being queried has been reused. That means you might end up retrieving an information referring to another process in case the original one this instance refers to is gone in the meantime. The only exceptions for which process identity is pre-emptively checked are: - parent - get_children() - set_nice() - suspend() - resume() - send_signal() - terminate() - kill() To prevent this problem for all other methods you can: - use is_running() before querying the process - if you're continuously iterating over a set of Process instances use process_iter() which pre-emptively checks process identity for every yielded instance """ if not _PY3: if not isinstance(pid, (int, long)): raise TypeError('pid must be an integer') if pid < 0: raise ValueError('pid must be a positive integer') self._pid = pid self._gone = False self._ppid = None # platform-specific modules define an _psplatform.Process # implementation class self._platform_impl = _psplatform.Process(pid) self._last_sys_cpu_times = None self._last_proc_cpu_times = None # cache creation time for later use in is_running() method try: self.create_time except AccessDenied: pass except NoSuchProcess: raise NoSuchProcess(pid, None, 'no process found with pid %s' % pid)
def get_memory_maps(self): try: raw = _psutil_mswindows.get_process_memory_maps(self.pid) except OSError: # XXX - can't use wrap_exceptions decorator as we're # returning a generator; probably needs refactoring. err = sys.exc_info()[1] if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED): raise AccessDenied(self.pid, self._process_name) if err.errno == errno.ESRCH: raise NoSuchProcess(self.pid, self._process_name) raise else: for addr, perm, path, rss in raw: path = _convert_raw_path(path) addr = hex(addr) yield (addr, perm, path, rss)
def send_signal(self, sig): """Send a signal to process pre-emptively checking whether PID has been reused (see signal module constants) . On Windows only SIGTERM is valid and is treated as an alias for kill(). """ if os.name == 'posix': try: os.kill(self.pid, sig) except OSError: err = sys.exc_info()[1] name = self._platform_impl._process_name if err.errno == errno.ESRCH: self._gone = True raise NoSuchProcess(self.pid, name) if err.errno == errno.EPERM: raise AccessDenied(self.pid, name) raise else: if sig == signal.SIGTERM: self._platform_impl.kill_process() else: raise ValueError("only SIGTERM is supported on Windows")
def wrapper(self, *args, **kwargs): if not self.is_running(): raise NoSuchProcess(self.pid, self._platform_impl._process_name) return fun(self, *args, **kwargs)
def get_process_cmdline(self): """Return process cmdline as a list of arguments.""" if not pid_exists(self.pid): raise NoSuchProcess(self.pid, self._process_name) return _psutil_osx.get_process_cmdline(self.pid)
def get_process_ppid(self): """Return process parent pid.""" try: return get_ppid_map()[self.pid] except KeyError: raise NoSuchProcess(self.pid, self._process_name)