diff options
author | Guido Günther <agx@sigxcpu.org> | 2014-04-18 12:06:46 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2014-04-18 14:52:35 +0200 |
commit | 2db247f179c3ab0f350bb3c9848ccc990ad761bc (patch) | |
tree | c51deee7b10b9f764a98c05c6426ca95a50a14bb /whatmaps/process.py | |
parent | 0e8224cf4b6d2a5ef6e8c7165dc6143db3cbc482 (diff) |
Split out and test Process
Diffstat (limited to 'whatmaps/process.py')
-rw-r--r-- | whatmaps/process.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/whatmaps/process.py b/whatmaps/process.py new file mode 100644 index 0000000..3fe23f3 --- /dev/null +++ b/whatmaps/process.py @@ -0,0 +1,77 @@ +#!/usr/bin/python -u +# vim: set fileencoding=utf-8 : +# +# (C) 2010,2014 Guido Günther <agx@sigxcpu.org> +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import errno +import logging +import os +import re + +class Process(object): + """A process - Linux only so far, needs /proc mounted""" + deleted_re = re.compile(r"(?P<exe>.*) \(deleted\)$") + + def __init__(self, pid, procfs=None): + self.procfs = procfs or '/proc' + self.pid = pid + self.mapped = [] + self.deleted = False + try: + self.exe = os.readlink(self._procpath(str(self.pid), 'exe')) + m = self.deleted_re.match(self.exe) + if m: + self.exe = m.group('exe') + self.deleted = True + logging.error("Using deleted exe %s", self.exe) + if not os.path.exists(self.exe): + logging.debug("%s doesn't exist", self.exe) + self.cmdline = open(self._procpath('%d/cmdline' % self.pid)).read() + except OSError: + self.exe = None + self.cmdline = None + + def _procpath(self, *args): + """ + Return a path relative to the current procfs bsae + """ + return os.path.join(self.procfs, *args) + + def _read_maps(self): + """Read the SOs from /proc/<pid>/maps""" + try: + f = file(self._procpath('%d/maps' % self.pid)) + except IOError as e: + # ignore killed process + if e.errno != errno.ENOENT: + raise + return + for line in f: + try: + so = line.split()[5].strip() + self.mapped.append(so) + except IndexError: + pass + + def maps(self, path): + """Check if the process maps the object at path""" + if not self.mapped: + self._read_maps() + + return True if path in self.mapped else False + + def __repr__(self): + return "<Process object pid:%d>" % self.pid |