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

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 6 years, 12 months 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):
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, OSError):
346 return None
335 347
336 def append_line(self, line): 348 def append_line(self, line):
337 entry = self.parse_line(line) 349 entry = self.parse_line(line)
338 if entry: 350 if entry:
339 self._append_entry(entry) 351 self._append_entry(entry)
340 return entry 352 return entry
341 353
342 @staticmethod 354 @staticmethod
343 def parse_line(line): 355 def parse_line(line):
344 matched = ProcMaps.MAPS_PATTERN.match(line) 356 matched = ProcMaps.MAPS_PATTERN.match(line)
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 560
549 @staticmethod 561 @staticmethod
550 def load(pid, maps): 562 def load(pid, maps):
551 total_present = 0 563 total_present = 0
552 total_swapped = 0 564 total_swapped = 0
553 total_vsize = 0 565 total_vsize = 0
554 in_process_dup = 0 566 in_process_dup = 0
555 vma_internals = collections.OrderedDict() 567 vma_internals = collections.OrderedDict()
556 process_pageframe_set = set() 568 process_pageframe_set = set()
557 569
558 pagemap_fd = os.open( 570 try:
559 os.path.join('/proc', str(pid), 'pagemap'), os.O_RDONLY) 571 pagemap_fd = os.open(
572 os.path.join('/proc', str(pid), 'pagemap'), os.O_RDONLY)
573 except (IOError, OSError):
574 return None
560 for vma in maps: 575 for vma in maps:
561 present = 0 576 present = 0
562 swapped = 0 577 swapped = 0
563 vsize = 0 578 vsize = 0
564 pageframes = collections.defaultdict(int) 579 pageframes = collections.defaultdict(int)
565 begin_offset = ProcPagemap._offset(vma.begin) 580 begin_offset = ProcPagemap._offset(vma.begin)
566 chunk_size = ProcPagemap._offset(vma.end) - begin_offset 581 chunk_size = ProcPagemap._offset(vma.end) - begin_offset
567 os.lseek(pagemap_fd, begin_offset, os.SEEK_SET) 582 try:
568 buf = os.read(pagemap_fd, chunk_size) 583 os.lseek(pagemap_fd, begin_offset, os.SEEK_SET)
584 buf = os.read(pagemap_fd, chunk_size)
585 except (IOError, OSError):
586 return None
569 if len(buf) < chunk_size: 587 if len(buf) < chunk_size:
570 _LOGGER.warn('Failed to read pagemap at 0x%x in %d.' % (vma.begin, pid)) 588 _LOGGER.warn('Failed to read pagemap at 0x%x in %d.' % (vma.begin, pid))
571 pagemap_values = struct.unpack( 589 pagemap_values = struct.unpack(
572 '=%dQ' % (len(buf) / ProcPagemap._BYTES_PER_PAGEMAP_VALUE), buf) 590 '=%dQ' % (len(buf) / ProcPagemap._BYTES_PER_PAGEMAP_VALUE), buf)
573 for pagemap_value in pagemap_values: 591 for pagemap_value in pagemap_values:
574 vsize += ProcPagemap._BYTES_PER_OS_PAGE 592 vsize += ProcPagemap._BYTES_PER_OS_PAGE
575 if pagemap_value & ProcPagemap._MASK_PRESENT: 593 if pagemap_value & ProcPagemap._MASK_PRESENT:
576 if (pagemap_value & ProcPagemap._MASK_PFN) in process_pageframe_set: 594 if (pagemap_value & ProcPagemap._MASK_PFN) in process_pageframe_set:
577 in_process_dup += ProcPagemap._BYTES_PER_OS_PAGE 595 in_process_dup += ProcPagemap._BYTES_PER_OS_PAGE
578 else: 596 else:
579 process_pageframe_set.add(pagemap_value & ProcPagemap._MASK_PFN) 597 process_pageframe_set.add(pagemap_value & ProcPagemap._MASK_PFN)
580 if (pagemap_value & ProcPagemap._MASK_PFN) not in pageframes: 598 if (pagemap_value & ProcPagemap._MASK_PFN) not in pageframes:
581 present += ProcPagemap._BYTES_PER_OS_PAGE 599 present += ProcPagemap._BYTES_PER_OS_PAGE
582 pageframes[pagemap_value & ProcPagemap._MASK_PFN] += 1 600 pageframes[pagemap_value & ProcPagemap._MASK_PFN] += 1
583 if pagemap_value & ProcPagemap._MASK_SWAPPED: 601 if pagemap_value & ProcPagemap._MASK_SWAPPED:
584 swapped += ProcPagemap._BYTES_PER_OS_PAGE 602 swapped += ProcPagemap._BYTES_PER_OS_PAGE
585 vma_internals[vma] = ProcPagemap.VMA(vsize, present, swapped, pageframes) 603 vma_internals[vma] = ProcPagemap.VMA(vsize, present, swapped, pageframes)
586 total_present += present 604 total_present += present
587 total_swapped += swapped 605 total_swapped += swapped
588 total_vsize += vsize 606 total_vsize += vsize
589 os.close(pagemap_fd) 607 try:
608 os.close(pagemap_fd)
609 except OSError:
610 return None
590 611
591 return ProcPagemap(total_vsize, total_present, total_swapped, 612 return ProcPagemap(total_vsize, total_present, total_swapped,
592 vma_internals, in_process_dup) 613 vma_internals, in_process_dup)
593 614
594 @staticmethod 615 @staticmethod
595 def _offset(virtual_address): 616 def _offset(virtual_address):
596 return virtual_address / ProcPagemap._VIRTUAL_TO_PAGEMAP_OFFSET 617 return virtual_address / ProcPagemap._VIRTUAL_TO_PAGEMAP_OFFSET
597 618
598 @property 619 @property
599 def vsize(self): 620 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, 741 print ' status: %d (Peak:%d)' % (procs[pid].status.vm_rss * 1024,
721 procs[pid].status.vm_hwm * 1024) 742 procs[pid].status.vm_hwm * 1024)
722 print ' smaps: %d' % (procs[pid].smaps.rss * 1024) 743 print ' smaps: %d' % (procs[pid].smaps.rss * 1024)
723 print 'pagemap: %d' % procs[pid].pagemap.present 744 print 'pagemap: %d' % procs[pid].pagemap.present
724 745
725 return 0 746 return 0
726 747
727 748
728 if __name__ == '__main__': 749 if __name__ == '__main__':
729 sys.exit(main(sys.argv)) 750 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