redo the smaps-parsing code to be a little more efficient. part of #3096
This commit is contained in:
		
							parent
							
								
									59708891e8
								
							
						
					
					
						commit
						8a733eea5d
					
				
							
								
								
									
										44
									
								
								shell/view/home/activitiesdonut.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										44
									
								
								shell/view/home/activitiesdonut.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -30,7 +30,7 @@ from sugar.graphics.palette import Palette
 | 
				
			|||||||
from sugar.graphics import style
 | 
					from sugar.graphics import style
 | 
				
			||||||
from sugar.graphics import xocolor
 | 
					from sugar.graphics import xocolor
 | 
				
			||||||
from sugar import profile
 | 
					from sugar import profile
 | 
				
			||||||
from proc_smaps import ProcSmaps
 | 
					import proc_smaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# TODO: rgb_to_html and html_to_rgb are useful elsewhere 
 | 
					# TODO: rgb_to_html and html_to_rgb are useful elsewhere 
 | 
				
			||||||
#       we should put this in a common module 
 | 
					#       we should put this in a common module 
 | 
				
			||||||
@ -186,6 +186,7 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem):
 | 
				
			|||||||
        self._activities = []
 | 
					        self._activities = []
 | 
				
			||||||
        self._shell = shell
 | 
					        self._shell = shell
 | 
				
			||||||
        self._angles = []
 | 
					        self._angles = []
 | 
				
			||||||
 | 
					        self._shell_mappings = proc_smaps.get_shared_mapping_names(os.getpid())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._model = shell.get_model().get_home()
 | 
					        self._model = shell.get_model().get_home()
 | 
				
			||||||
        self._model.connect('activity-added', self._activity_added_cb)
 | 
					        self._model.connect('activity-added', self._activity_added_cb)
 | 
				
			||||||
@ -282,23 +283,11 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem):
 | 
				
			|||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _update_activity_sizes(self):
 | 
					    def _update_activity_sizes(self):
 | 
				
			||||||
        # First, get the shell's memory mappings; this memory won't be
 | 
					 | 
				
			||||||
        # counted against the memory used by activities, since it
 | 
					 | 
				
			||||||
        # would still be in use even if all activities exited.
 | 
					 | 
				
			||||||
        shell_mappings = {}
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            shell_smaps = ProcSmaps(os.getpid())
 | 
					 | 
				
			||||||
            for mapping in shell_smaps.mappings:
 | 
					 | 
				
			||||||
                if mapping.shared_clean > 0 or mapping.shared_dirty > 0:
 | 
					 | 
				
			||||||
                    shell_mappings[mapping.name] = mapping
 | 
					 | 
				
			||||||
        except Exception, e:
 | 
					 | 
				
			||||||
            logging.warn('ActivitiesDonut: could not read own smaps: %r' % e)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Get the memory mappings of each process that hosts an
 | 
					        # Get the memory mappings of each process that hosts an
 | 
				
			||||||
        # activity, and count how many activity instances each
 | 
					        # activity, and count how many activity instances each
 | 
				
			||||||
        # activity process hosts, and how many processes are mapping
 | 
					        # activity process hosts, and how many processes are mapping
 | 
				
			||||||
        # each shared library, etc
 | 
					        # each shared library, etc
 | 
				
			||||||
        process_smaps = {}
 | 
					        process_mappings = {}
 | 
				
			||||||
        num_activities = {}
 | 
					        num_activities = {}
 | 
				
			||||||
        num_mappings = {}
 | 
					        num_mappings = {}
 | 
				
			||||||
        unknown_size_activities = 0
 | 
					        unknown_size_activities = 0
 | 
				
			||||||
@ -314,15 +303,14 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem):
 | 
				
			|||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                smaps = ProcSmaps(pid)
 | 
					                mappings = proc_smaps.get_mappings(pid, self._shell_mappings)
 | 
				
			||||||
                self._subtract_mappings(smaps, shell_mappings)
 | 
					                for mapping in mappings:
 | 
				
			||||||
                for mapping in smaps.mappings:
 | 
					                    if mapping.shared > 0:
 | 
				
			||||||
                    if mapping.shared_clean > 0 or mapping.shared_dirty > 0:
 | 
					 | 
				
			||||||
                        if num_mappings.has_key(mapping.name):
 | 
					                        if num_mappings.has_key(mapping.name):
 | 
				
			||||||
                            num_mappings[mapping.name] += 1
 | 
					                            num_mappings[mapping.name] += 1
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
                            num_mappings[mapping.name] = 1
 | 
					                            num_mappings[mapping.name] = 1
 | 
				
			||||||
                process_smaps[pid] = smaps
 | 
					                process_mappings[pid] = mappings
 | 
				
			||||||
                num_activities[pid] = 1
 | 
					                num_activities[pid] = 1
 | 
				
			||||||
            except Exception, e:
 | 
					            except Exception, e:
 | 
				
			||||||
                logging.warn('ActivitiesDonut: could not read /proc/%s/smaps: %r'
 | 
					                logging.warn('ActivitiesDonut: could not read /proc/%s/smaps: %r'
 | 
				
			||||||
@ -333,16 +321,16 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem):
 | 
				
			|||||||
        total_activity_size = 0
 | 
					        total_activity_size = 0
 | 
				
			||||||
        for activity in self._model:
 | 
					        for activity in self._model:
 | 
				
			||||||
            pid = activity.get_pid()
 | 
					            pid = activity.get_pid()
 | 
				
			||||||
            if not process_smaps.has_key(pid):
 | 
					            if not process_mappings.has_key(pid):
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            smaps = process_smaps[pid]
 | 
					            mappings = process_mappings[pid]
 | 
				
			||||||
            size = 0
 | 
					            size = 0
 | 
				
			||||||
            for mapping in smaps.mappings:
 | 
					            for mapping in mappings:
 | 
				
			||||||
                size += mapping.private_clean + mapping.private_dirty
 | 
					                size += mapping.private
 | 
				
			||||||
                if mapping.shared_clean + mapping.shared_dirty > 0:
 | 
					                if mapping.shared > 0:
 | 
				
			||||||
                    num = num_mappings[mapping.name]
 | 
					                    num = num_mappings[mapping.name]
 | 
				
			||||||
                    size += (mapping.shared_clean + mapping.shared_dirty) / num
 | 
					                    size += mapping.shared / num
 | 
				
			||||||
            process_size[pid] = size
 | 
					            process_size[pid] = size
 | 
				
			||||||
            total_activity_size += size / num_activities[pid]
 | 
					            total_activity_size += size / num_activities[pid]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -406,12 +394,6 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem):
 | 
				
			|||||||
                    if icon.size > _MIN_WEDGE_SIZE:
 | 
					                    if icon.size > _MIN_WEDGE_SIZE:
 | 
				
			||||||
                        icon.size -= (icon.size - _MIN_WEDGE_SIZE) * reduction
 | 
					                        icon.size -= (icon.size - _MIN_WEDGE_SIZE) * reduction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _subtract_mappings(self, smaps, mappings_to_remove):
 | 
					 | 
				
			||||||
        for mapping in smaps.mappings:
 | 
					 | 
				
			||||||
            if mappings_to_remove.has_key(mapping.name):
 | 
					 | 
				
			||||||
                mapping.shared_clean = 0
 | 
					 | 
				
			||||||
                mapping.shared_dirty = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _compute_angles(self):
 | 
					    def _compute_angles(self):
 | 
				
			||||||
        self._angles = []
 | 
					        self._angles = []
 | 
				
			||||||
        if len(self._activities) == 0:
 | 
					        if len(self._activities) == 0:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										231
									
								
								shell/view/home/proc_smaps.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										231
									
								
								shell/view/home/proc_smaps.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -1,149 +1,106 @@
 | 
				
			|||||||
####################################################################
 | 
					# Copyright (C) 2007 Red Hat, Inc.
 | 
				
			||||||
# This class open the /proc/PID/maps and /proc/PID/smaps files
 | 
					#
 | 
				
			||||||
# to get useful information about the real memory usage
 | 
					# 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
 | 
					import os
 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
_smaps_has_references = None
 | 
					# /proc/PID/maps consists of a number of lines like this:
 | 
				
			||||||
 | 
					# 00400000-004b1000 r-xp 00000000 fd:00 5767206                  /bin/bash
 | 
				
			||||||
# Parse the /proc/PID/smaps file
 | 
					# 006b1000-006bb000 rw-p 000b1000 fd:00 5767206                  /bin/bash
 | 
				
			||||||
class ProcSmaps:
 | 
					# 006bb000-006c0000 rw-p 006bb000 00:00 0 
 | 
				
			||||||
 | 
					# ...
 | 
				
			||||||
    mappings = [] # Devices information
 | 
					# The fields are: address, permissions, offset, device, inode, and
 | 
				
			||||||
    
 | 
					# (for non-anonymous mappings) pathname.
 | 
				
			||||||
    def __init__(self, pid):
 | 
					#
 | 
				
			||||||
        global _smaps_has_references
 | 
					# /proc/PID/smaps gives additional information for each mapping:
 | 
				
			||||||
        if _smaps_has_references is None:
 | 
					# 00400000-004b1000 r-xp 00000000 fd:00 5767206                  /bin/bash
 | 
				
			||||||
            _smaps_has_references = os.path.isfile('/proc/%s/clear_refs' %
 | 
					# Size:               708 kB
 | 
				
			||||||
                                                   os.getpid())
 | 
					# Rss:                476 kB
 | 
				
			||||||
 | 
					# Shared_Clean:       468 kB
 | 
				
			||||||
        smapfile = "/proc/%s/smaps" % pid
 | 
					 | 
				
			||||||
        self.mappings = []
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        # Coded by Federico Mena (script)
 | 
					 | 
				
			||||||
        infile = open(smapfile, "r")
 | 
					 | 
				
			||||||
        input = infile.read()
 | 
					 | 
				
			||||||
        infile.close()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        lines = input.splitlines()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        num_lines = len (lines)
 | 
					 | 
				
			||||||
        line_idx = 0
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        # 08065000-08067000 rw-p 0001c000 03:01 147613     /opt/gnome/bin/evolution-2.6
 | 
					 | 
				
			||||||
        # Size:                 8 kB
 | 
					 | 
				
			||||||
        # Rss:                  8 kB
 | 
					 | 
				
			||||||
        # Shared_Clean:         0 kB
 | 
					 | 
				
			||||||
# Shared_Dirty:         0 kB
 | 
					# Shared_Dirty:         0 kB
 | 
				
			||||||
# Private_Clean:        8 kB
 | 
					# Private_Clean:        8 kB
 | 
				
			||||||
# Private_Dirty:        0 kB
 | 
					# Private_Dirty:        0 kB
 | 
				
			||||||
        # Referenced:           4 kb -> Introduced in kernel 2.6.22
 | 
					# Referenced:           0 kb
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The "Referenced" line only appears in kernel 2.6.22 and later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while num_lines > 0:
 | 
					def get_shared_mapping_names(pid):
 | 
				
			||||||
            fields = lines[line_idx].split (" ", 5)
 | 
					    """Returns a set of the files for which PID has a shared mapping"""
 | 
				
			||||||
            if len (fields) == 6:
 | 
					 | 
				
			||||||
                (offsets, permissions, bin_permissions, device, inode, name) = fields
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                (offsets, permissions, bin_permissions, device, inode) = fields
 | 
					 | 
				
			||||||
                name = ""
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
            size          = self.parse_smaps_size_line (lines[line_idx + 1])
 | 
					    mappings = set()
 | 
				
			||||||
            rss           = self.parse_smaps_size_line (lines[line_idx + 2])
 | 
					    infile = open("/proc/%s/maps" % pid, "r")
 | 
				
			||||||
            shared_clean  = self.parse_smaps_size_line (lines[line_idx + 3])
 | 
					    for line in infile:
 | 
				
			||||||
            shared_dirty  = self.parse_smaps_size_line (lines[line_idx + 4])
 | 
					        # sharable mappings are non-anonymous and either read-only
 | 
				
			||||||
            private_clean = self.parse_smaps_size_line (lines[line_idx + 5])
 | 
					        # (permissions "r-..") or writable but explicitly marked
 | 
				
			||||||
            private_dirty = self.parse_smaps_size_line (lines[line_idx + 6])
 | 
					        # shared ("rw.s")
 | 
				
			||||||
            if _smaps_has_references:
 | 
					 | 
				
			||||||
                referenced = self.parse_smaps_size_line (lines[line_idx + 7])
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                referenced = None
 | 
					 | 
				
			||||||
            name = name.strip ()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            mapping = Mapping (size, rss, shared_clean, shared_dirty, \
 | 
					 | 
				
			||||||
                private_clean, private_dirty, referenced, permissions, name)
 | 
					 | 
				
			||||||
            self.mappings.append (mapping)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if _smaps_has_references:
 | 
					 | 
				
			||||||
                num_lines -= 8
 | 
					 | 
				
			||||||
                line_idx += 8
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                num_lines -= 7
 | 
					 | 
				
			||||||
                line_idx += 7
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if _smaps_has_references:
 | 
					 | 
				
			||||||
            self._clear_reference(pid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _clear_reference(self, pid):
 | 
					 | 
				
			||||||
      os.system("echo 1 > /proc/%s/clear_refs" % pid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Parses a line of the form "foo: 42 kB" and returns an integer for the "42" field
 | 
					 | 
				
			||||||
    def parse_smaps_size_line (self, line):
 | 
					 | 
				
			||||||
        # Rss:                  8 kB
 | 
					 | 
				
			||||||
        fields = line.split()
 | 
					        fields = line.split()
 | 
				
			||||||
        return int(fields[1])
 | 
					        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, shared)
 | 
				
			||||||
 | 
					        mappings.append (mapping)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return mappings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Mapping:
 | 
					class Mapping:
 | 
				
			||||||
    def __init__ (self, size, rss, shared_clean, shared_dirty, \
 | 
					    def __init__ (self, name, private, shared):
 | 
				
			||||||
            private_clean, private_dirty, referenced, permissions, name):
 | 
					 | 
				
			||||||
        self.size = size
 | 
					 | 
				
			||||||
        self.rss = rss
 | 
					 | 
				
			||||||
        self.shared_clean = shared_clean
 | 
					 | 
				
			||||||
        self.shared_dirty = shared_dirty
 | 
					 | 
				
			||||||
        self.private_clean = private_clean
 | 
					 | 
				
			||||||
        self.private_dirty = private_dirty
 | 
					 | 
				
			||||||
        self.referenced  = referenced
 | 
					 | 
				
			||||||
        self.permissions = permissions
 | 
					 | 
				
			||||||
        self.name = name
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        self.private = private
 | 
				
			||||||
# Parse /proc/PID/maps file to get the clean memory usage by process,
 | 
					        self.shared = shared
 | 
				
			||||||
# we avoid lines with backed-files
 | 
					 | 
				
			||||||
class ProcMaps:
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    clean_size = 0
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    def __init__(self, pid):
 | 
					 | 
				
			||||||
        mapfile = "/proc/%s/maps" % pid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            infile = open(mapfile, "r")
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            print "Error trying " + mapfile
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        sum = 0
 | 
					 | 
				
			||||||
        to_data_do = {
 | 
					 | 
				
			||||||
            "[anon]": self.parse_size_line,
 | 
					 | 
				
			||||||
            "[heap]": self.parse_size_line
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        for line in infile:
 | 
					 | 
				
			||||||
            arr = line.split()
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            # Just parse writable mapped areas
 | 
					 | 
				
			||||||
            if arr[1][1] != "w":
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if len(arr) == 6:                
 | 
					 | 
				
			||||||
                # if we got a backed-file we skip this info
 | 
					 | 
				
			||||||
                if os.path.isfile(arr[5]):
 | 
					 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    line_size = to_data_do.get(arr[5], self.skip)(line)
 | 
					 | 
				
			||||||
                    sum += line_size
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                line_size = self.parse_size_line(line)
 | 
					 | 
				
			||||||
                sum += line_size
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
        infile.close()
 | 
					 | 
				
			||||||
        self.clean_size = sum
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    def skip(self, line):
 | 
					 | 
				
			||||||
        return 0
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    # Parse a maps line and return the mapped size
 | 
					 | 
				
			||||||
    def parse_size_line(self, line):
 | 
					 | 
				
			||||||
        start, end = line.split()[0].split('-')
 | 
					 | 
				
			||||||
        size = int(end, 16) - int(start, 16)            
 | 
					 | 
				
			||||||
        return size
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user