Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: tools/linux/procfs.py

Issue 108073002: Error handling and refactoring in tools/linux/procfs.py, and rename multi-process-rss.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/multi-process-rss.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # A Python library to read and store procfs (/proc) information on Linux. 6 # A Python library to read and store procfs (/proc) information on Linux.
7 # 7 #
8 # Each information storage class in this file stores original data as original 8 # Each information storage class in this file stores original data as original
9 # as reasonablly possible. Translation is done when requested. It is to make it 9 # as reasonablly possible. Translation is done when requested. It is to make it
10 # always possible to probe the original data. 10 # always possible to probe the original data.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 def load_file(stat_f): 85 def load_file(stat_f):
86 raw = stat_f.readlines() 86 raw = stat_f.readlines()
87 stat = ProcStat._PATTERN.match(raw[0]) 87 stat = ProcStat._PATTERN.match(raw[0])
88 return ProcStat(raw, 88 return ProcStat(raw,
89 stat.groupdict().get('PID'), 89 stat.groupdict().get('PID'),
90 stat.groupdict().get('VSIZE'), 90 stat.groupdict().get('VSIZE'),
91 stat.groupdict().get('RSS')) 91 stat.groupdict().get('RSS'))
92 92
93 @staticmethod 93 @staticmethod
94 def load(pid): 94 def load(pid):
95 with open(os.path.join('/proc', str(pid), 'stat'), 'r') as stat_f: 95 try:
96 return ProcStat.load_file(stat_f) 96 with open(os.path.join('/proc', str(pid), 'stat'), 'r') as stat_f:
97 return ProcStat.load_file(stat_f)
98 except IOError:
99 return None
97 100
98 @property 101 @property
99 def raw(self): 102 def raw(self):
100 return self._raw 103 return self._raw
101 104
102 @property 105 @property
103 def pid(self): 106 def pid(self):
104 return int(self._pid) 107 return int(self._pid)
105 108
106 @property 109 @property
(...skipping 21 matching lines...) Expand all
128 self._size = size 131 self._size = size
129 self._resident = resident 132 self._resident = resident
130 self._share = share 133 self._share = share
131 self._text = text 134 self._text = text
132 self._lib = lib 135 self._lib = lib
133 self._data = data 136 self._data = data
134 self._dt = dt 137 self._dt = dt
135 138
136 @staticmethod 139 @staticmethod
137 def load_file(statm_f): 140 def load_file(statm_f):
138 raw = statm_f.readlines() 141 try:
142 raw = statm_f.readlines()
143 except (IOError, OSError):
peria 2013/12/09 05:08:13 You use two styles to catch multiple-type exceptio
144 return None
139 statm = ProcStatm._PATTERN.match(raw[0]) 145 statm = ProcStatm._PATTERN.match(raw[0])
140 return ProcStatm(raw, 146 return ProcStatm(raw,
141 statm.groupdict().get('SIZE'), 147 statm.groupdict().get('SIZE'),
142 statm.groupdict().get('RESIDENT'), 148 statm.groupdict().get('RESIDENT'),
143 statm.groupdict().get('SHARE'), 149 statm.groupdict().get('SHARE'),
144 statm.groupdict().get('TEXT'), 150 statm.groupdict().get('TEXT'),
145 statm.groupdict().get('LIB'), 151 statm.groupdict().get('LIB'),
146 statm.groupdict().get('DATA'), 152 statm.groupdict().get('DATA'),
147 statm.groupdict().get('DT')) 153 statm.groupdict().get('DT'))
148 154
149 @staticmethod 155 @staticmethod
150 def load(pid): 156 def load(pid):
151 with open(os.path.join('/proc', str(pid), 'statm'), 'r') as statm_f: 157 try:
152 return ProcStatm.load_file(statm_f) 158 with open(os.path.join('/proc', str(pid), 'statm'), 'r') as statm_f:
159 return ProcStatm.load_file(statm_f)
160 except (IOError, OSError):
161 return None
153 162
154 @property 163 @property
155 def raw(self): 164 def raw(self):
156 return self._raw 165 return self._raw
157 166
158 @property 167 @property
159 def size(self): 168 def size(self):
160 return int(self._size) 169 return int(self._size)
161 170
162 @property 171 @property
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 332
324 @staticmethod 333 @staticmethod
325 def load_file(maps_f): 334 def load_file(maps_f):
326 table = ProcMaps() 335 table = ProcMaps()
327 for line in maps_f: 336 for line in maps_f:
328 table.append_line(line) 337 table.append_line(line)
329 return table 338 return table
330 339
331 @staticmethod 340 @staticmethod
332 def load(pid): 341 def load(pid):
333 with open(os.path.join('/proc', str(pid), 'maps'), 'r') as maps_f: 342 try:
334 return ProcMaps.load_file(maps_f) 343 with open(os.path.join('/proc', str(pid), 'maps'), 'r') as maps_f:
344 return ProcMaps.load_file(maps_f)
345 except IOError:
346 return None
347 except OSError:
348 return None
335 349
336 def append_line(self, line): 350 def append_line(self, line):
337 entry = self.parse_line(line) 351 entry = self.parse_line(line)
338 if entry: 352 if entry:
339 self._append_entry(entry) 353 self._append_entry(entry)
340 return entry 354 return entry
341 355
342 @staticmethod 356 @staticmethod
343 def parse_line(line): 357 def parse_line(line):
344 matched = ProcMaps.MAPS_PATTERN.match(line) 358 matched = ProcMaps.MAPS_PATTERN.match(line)
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 562
549 @staticmethod 563 @staticmethod
550 def load(pid, maps): 564 def load(pid, maps):
551 total_present = 0 565 total_present = 0
552 total_swapped = 0 566 total_swapped = 0
553 total_vsize = 0 567 total_vsize = 0
554 in_process_dup = 0 568 in_process_dup = 0
555 vma_internals = collections.OrderedDict() 569 vma_internals = collections.OrderedDict()
556 process_pageframe_set = set() 570 process_pageframe_set = set()
557 571
558 pagemap_fd = os.open( 572 try:
559 os.path.join('/proc', str(pid), 'pagemap'), os.O_RDONLY) 573 pagemap_fd = os.open(
574 os.path.join('/proc', str(pid), 'pagemap'), os.O_RDONLY)
575 except IOError:
576 return None
577 except OSError:
578 return None
560 for vma in maps: 579 for vma in maps:
561 present = 0 580 present = 0
562 swapped = 0 581 swapped = 0
563 vsize = 0 582 vsize = 0
564 pageframes = collections.defaultdict(int) 583 pageframes = collections.defaultdict(int)
565 begin_offset = ProcPagemap._offset(vma.begin) 584 begin_offset = ProcPagemap._offset(vma.begin)
566 chunk_size = ProcPagemap._offset(vma.end) - begin_offset 585 chunk_size = ProcPagemap._offset(vma.end) - begin_offset
567 os.lseek(pagemap_fd, begin_offset, os.SEEK_SET) 586 try:
568 buf = os.read(pagemap_fd, chunk_size) 587 os.lseek(pagemap_fd, begin_offset, os.SEEK_SET)
588 buf = os.read(pagemap_fd, chunk_size)
589 except IOError:
590 return None
591 except OSError:
592 return None
569 if len(buf) < chunk_size: 593 if len(buf) < chunk_size:
570 _LOGGER.warn('Failed to read pagemap at 0x%x in %d.' % (vma.begin, pid)) 594 _LOGGER.warn('Failed to read pagemap at 0x%x in %d.' % (vma.begin, pid))
571 pagemap_values = struct.unpack( 595 pagemap_values = struct.unpack(
572 '=%dQ' % (len(buf) / ProcPagemap._BYTES_PER_PAGEMAP_VALUE), buf) 596 '=%dQ' % (len(buf) / ProcPagemap._BYTES_PER_PAGEMAP_VALUE), buf)
573 for pagemap_value in pagemap_values: 597 for pagemap_value in pagemap_values:
574 vsize += ProcPagemap._BYTES_PER_OS_PAGE 598 vsize += ProcPagemap._BYTES_PER_OS_PAGE
575 if pagemap_value & ProcPagemap._MASK_PRESENT: 599 if pagemap_value & ProcPagemap._MASK_PRESENT:
576 if (pagemap_value & ProcPagemap._MASK_PFN) in process_pageframe_set: 600 if (pagemap_value & ProcPagemap._MASK_PFN) in process_pageframe_set:
577 in_process_dup += ProcPagemap._BYTES_PER_OS_PAGE 601 in_process_dup += ProcPagemap._BYTES_PER_OS_PAGE
578 else: 602 else:
579 process_pageframe_set.add(pagemap_value & ProcPagemap._MASK_PFN) 603 process_pageframe_set.add(pagemap_value & ProcPagemap._MASK_PFN)
580 if (pagemap_value & ProcPagemap._MASK_PFN) not in pageframes: 604 if (pagemap_value & ProcPagemap._MASK_PFN) not in pageframes:
581 present += ProcPagemap._BYTES_PER_OS_PAGE 605 present += ProcPagemap._BYTES_PER_OS_PAGE
582 pageframes[pagemap_value & ProcPagemap._MASK_PFN] += 1 606 pageframes[pagemap_value & ProcPagemap._MASK_PFN] += 1
583 if pagemap_value & ProcPagemap._MASK_SWAPPED: 607 if pagemap_value & ProcPagemap._MASK_SWAPPED:
584 swapped += ProcPagemap._BYTES_PER_OS_PAGE 608 swapped += ProcPagemap._BYTES_PER_OS_PAGE
585 vma_internals[vma] = ProcPagemap.VMA(vsize, present, swapped, pageframes) 609 vma_internals[vma] = ProcPagemap.VMA(vsize, present, swapped, pageframes)
586 total_present += present 610 total_present += present
587 total_swapped += swapped 611 total_swapped += swapped
588 total_vsize += vsize 612 total_vsize += vsize
589 os.close(pagemap_fd) 613 try:
614 os.close(pagemap_fd)
615 except OSError:
616 return None
590 617
591 return ProcPagemap(total_vsize, total_present, total_swapped, 618 return ProcPagemap(total_vsize, total_present, total_swapped,
592 vma_internals, in_process_dup) 619 vma_internals, in_process_dup)
593 620
594 @staticmethod 621 @staticmethod
595 def _offset(virtual_address): 622 def _offset(virtual_address):
596 return virtual_address / ProcPagemap._VIRTUAL_TO_PAGEMAP_OFFSET 623 return virtual_address / ProcPagemap._VIRTUAL_TO_PAGEMAP_OFFSET
597 624
598 @property 625 @property
599 def vsize(self): 626 def vsize(self):
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 print ' status: %d (Peak:%d)' % (procs[pid].status.vm_rss * 1024, 747 print ' status: %d (Peak:%d)' % (procs[pid].status.vm_rss * 1024,
721 procs[pid].status.vm_hwm * 1024) 748 procs[pid].status.vm_hwm * 1024)
722 print ' smaps: %d' % (procs[pid].smaps.rss * 1024) 749 print ' smaps: %d' % (procs[pid].smaps.rss * 1024)
723 print 'pagemap: %d' % procs[pid].pagemap.present 750 print 'pagemap: %d' % procs[pid].pagemap.present
724 751
725 return 0 752 return 0
726 753
727 754
728 if __name__ == '__main__': 755 if __name__ == '__main__':
729 sys.exit(main(sys.argv)) 756 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | tools/multi-process-rss.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698