2007-09-11 17:36:33 +02:00
|
|
|
# Copyright (C) 2007 Red Hat, Inc.
|
|
|
|
#
|
|
|
|
# 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 2 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, write to the Free Software
|
|
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
|
|
|
# USA
|
2007-08-24 16:28:33 +02:00
|
|
|
|
|
|
|
import os
|
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
# /proc/PID/maps consists of a number of lines like this:
|
|
|
|
# 00400000-004b1000 r-xp 00000000 fd:00 5767206 /bin/bash
|
|
|
|
# 006b1000-006bb000 rw-p 000b1000 fd:00 5767206 /bin/bash
|
|
|
|
# 006bb000-006c0000 rw-p 006bb000 00:00 0
|
|
|
|
# ...
|
|
|
|
# The fields are: address, permissions, offset, device, inode, and
|
|
|
|
# (for non-anonymous mappings) pathname.
|
|
|
|
#
|
|
|
|
# /proc/PID/smaps gives additional information for each mapping:
|
|
|
|
# 00400000-004b1000 r-xp 00000000 fd:00 5767206 /bin/bash
|
|
|
|
# Size: 708 kB
|
|
|
|
# Rss: 476 kB
|
|
|
|
# Shared_Clean: 468 kB
|
|
|
|
# Shared_Dirty: 0 kB
|
|
|
|
# Private_Clean: 8 kB
|
|
|
|
# Private_Dirty: 0 kB
|
|
|
|
# Referenced: 0 kb
|
|
|
|
#
|
|
|
|
# The "Referenced" line only appears in kernel 2.6.22 and later.
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
def get_shared_mapping_names(pid):
|
|
|
|
"""Returns a set of the files for which PID has a shared mapping"""
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
mappings = set()
|
|
|
|
infile = open("/proc/%s/maps" % pid, "r")
|
|
|
|
for line in infile:
|
|
|
|
# sharable mappings are non-anonymous and either read-only
|
|
|
|
# (permissions "r-..") or writable but explicitly marked
|
|
|
|
# shared ("rw.s")
|
|
|
|
fields = line.split()
|
|
|
|
if len(fields) < 6 or not fields[5].startswith('/'):
|
|
|
|
continue
|
|
|
|
if fields[1][0] != 'r' or (fields[1][1] == 'w' and fields[1][3] != 's'):
|
|
|
|
continue
|
|
|
|
mappings.add(fields[5])
|
|
|
|
infile.close()
|
|
|
|
return mappings
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
_smaps_lines_per_entry = None
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
def get_mappings(pid, ignored_shared_mappings):
|
|
|
|
"""Returns a list of (name, private, shared) tuples describing the
|
|
|
|
memory mappings of PID. Shared mappings named in
|
|
|
|
ignored_shared_mappings are ignored
|
|
|
|
"""
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
global _smaps_lines_per_entry
|
|
|
|
if _smaps_lines_per_entry is None:
|
|
|
|
if os.path.isfile('/proc/%s/clear_refs' % os.getpid()):
|
|
|
|
_smaps_lines_per_entry = 8
|
|
|
|
else:
|
|
|
|
_smaps_lines_per_entry = 7
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
mappings = []
|
|
|
|
|
|
|
|
smapfile = "/proc/%s/smaps" % pid
|
|
|
|
infile = open(smapfile, "r")
|
|
|
|
input = infile.read()
|
|
|
|
infile.close()
|
|
|
|
lines = input.splitlines()
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
for line_idx in range(0, len(lines), _smaps_lines_per_entry):
|
|
|
|
name_idx = lines[line_idx].find('/')
|
|
|
|
if name_idx == -1:
|
|
|
|
name = None
|
|
|
|
else:
|
|
|
|
name = lines[line_idx][name_idx:]
|
|
|
|
|
|
|
|
private_clean = int(lines[line_idx + 5][14:-3])
|
|
|
|
private_dirty = int(lines[line_idx + 6][14:-3])
|
|
|
|
if name in ignored_shared_mappings:
|
|
|
|
shared_clean = 0
|
|
|
|
shared_dirty = 0
|
|
|
|
else:
|
|
|
|
shared_clean = int(lines[line_idx + 3][14:-3])
|
|
|
|
shared_dirty = int(lines[line_idx + 4][14:-3])
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-13 19:32:51 +02:00
|
|
|
mapping = Mapping(name, private_clean + private_dirty,
|
|
|
|
shared_clean + shared_dirty)
|
2007-09-11 17:36:33 +02:00
|
|
|
mappings.append (mapping)
|
2007-08-24 16:28:33 +02:00
|
|
|
|
2007-09-11 17:36:33 +02:00
|
|
|
return mappings
|
2007-08-24 16:28:33 +02:00
|
|
|
|
|
|
|
class Mapping:
|
2007-09-11 17:36:33 +02:00
|
|
|
def __init__ (self, name, private, shared):
|
2007-08-24 16:28:33 +02:00
|
|
|
self.name = name
|
2007-09-11 17:36:33 +02:00
|
|
|
self.private = private
|
|
|
|
self.shared = shared
|