Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/view/home/proc_smaps.py
blob: 6e1680f76eae834a730e218d6347dfd64464c4f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 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

import os

# /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.

def get_shared_mapping_names(pid):
    """Returns a set of the files for which PID has a shared mapping"""
    
    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

_smaps_lines_per_entry = None

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
    """

    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

    mappings = []
    
    smapfile = "/proc/%s/smaps" % pid
    infile = open(smapfile, "r")
    input = infile.read()
    infile.close()
    lines = input.splitlines()

    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])

        mapping = Mapping(name, private_clean + private_dirty,
                          shared_clean + shared_dirty)
        mappings.append (mapping)

    return mappings

class Mapping:
    def __init__ (self, name, private, shared):
        self.name = name
        self.private = private
        self.shared = shared