Exemple #1
0
    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()
Exemple #2
0
    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
Exemple #3
0
 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
Exemple #5
0
 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)
Exemple #6
0
    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)
Exemple #7
0
 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)
Exemple #8
0
 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")
Exemple #9
0
 def wrapper(self, *args, **kwargs):
     if not self.is_running():
         raise NoSuchProcess(self.pid, self._platform_impl._process_name)
     return fun(self, *args, **kwargs)
Exemple #10
0
 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)
Exemple #11
0
 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)