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

Side by Side Diff: tools/multi-process-rss.py

Issue 106973006: Add error handling and /proc/statm count in 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 | no next file » | 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 # Counts a resident set size (RSS) of multiple processes without double-counts. 6 # Counts a resident set size (RSS) of multiple processes without double-counts.
7 # If they share the same page frame, the page frame is counted only once. 7 # If they share the same page frame, the page frame is counted only once.
8 # 8 #
9 # Usage: 9 # Usage:
10 # ./multi-process-rss.py <pid>|<pid>r [...] 10 # ./multi-process-rss.py <pid>|<pid>r [...]
(...skipping 24 matching lines...) Expand all
35 class _NullHandler(logging.Handler): 35 class _NullHandler(logging.Handler):
36 def emit(self, record): 36 def emit(self, record):
37 pass 37 pass
38 38
39 39
40 _LOGGER = logging.getLogger('multi-process-rss') 40 _LOGGER = logging.getLogger('multi-process-rss')
41 _LOGGER.addHandler(_NullHandler()) 41 _LOGGER.addHandler(_NullHandler())
42 42
43 43
44 def _recursive_get_children(pid): 44 def _recursive_get_children(pid):
45 children = psutil.Process(pid).get_children() 45 try:
46 children = psutil.Process(pid).get_children()
47 except psutil.error.NoSuchProcess:
48 return []
46 descendant = [] 49 descendant = []
47 for child in children: 50 for child in children:
48 descendant.append(child.pid) 51 descendant.append(child.pid)
49 descendant.extend(_recursive_get_children(child.pid)) 52 descendant.extend(_recursive_get_children(child.pid))
50 return descendant 53 return descendant
51 54
52 55
53 def list_pids(argv): 56 def list_pids(argv):
54 pids = [] 57 pids = []
55 for arg in argv[1:]: 58 for arg in argv[1:]:
(...skipping 15 matching lines...) Expand all
71 pids = sorted(set(pids), key=pids.index) # uniq: maybe slow, but simple. 74 pids = sorted(set(pids), key=pids.index) # uniq: maybe slow, but simple.
72 75
73 return pids 76 return pids
74 77
75 78
76 def count_pageframes(pids): 79 def count_pageframes(pids):
77 pageframes = collections.defaultdict(int) 80 pageframes = collections.defaultdict(int)
78 pagemap_dct = {} 81 pagemap_dct = {}
79 for pid in pids: 82 for pid in pids:
80 maps = procfs.ProcMaps.load(pid) 83 maps = procfs.ProcMaps.load(pid)
81 pagemap_dct[pid] = procfs.ProcPagemap.load(pid, maps) 84 if not maps:
85 _LOGGER.warning('/proc/%d/maps not found.' % pid)
86 continue
87 pagemap = procfs.ProcPagemap.load(pid, maps)
88 if not pagemap:
89 _LOGGER.warning('/proc/%d/pagemap not found.' % pid)
90 continue
91 pagemap_dct[pid] = pagemap
82 92
83 for pid, pagemap in pagemap_dct.iteritems(): 93 for pid, pagemap in pagemap_dct.iteritems():
84 for vma in pagemap.vma_internals.itervalues(): 94 for vma in pagemap.vma_internals.itervalues():
85 for pageframe, number in vma.pageframes.iteritems(): 95 for pageframe, number in vma.pageframes.iteritems():
86 pageframes[pageframe] += number 96 pageframes[pageframe] += number
87 97
88 return pageframes 98 return pageframes
89 99
90 100
101 def count_statm(pids):
102 resident = 0
103 shared = 0
104 private = 0
105
106 for pid in pids:
107 statm = procfs.ProcStatm.load(pid)
108 if not statm:
109 _LOGGER.warning('/proc/%d/statm not found.' % pid)
110 continue
111 resident += statm.resident
112 shared += statm.share
113 private += (statm.resident - statm.share)
114
115 return (resident, shared, private)
116
117
91 def main(argv): 118 def main(argv):
92 logging_handler = logging.StreamHandler() 119 logging_handler = logging.StreamHandler()
93 logging_handler.setLevel(logging.WARNING) 120 logging_handler.setLevel(logging.WARNING)
94 logging_handler.setFormatter(logging.Formatter( 121 logging_handler.setFormatter(logging.Formatter(
95 '%(asctime)s:%(name)s:%(levelname)s:%(message)s')) 122 '%(asctime)s:%(name)s:%(levelname)s:%(message)s'))
96 123
97 _LOGGER.setLevel(logging.WARNING) 124 _LOGGER.setLevel(logging.WARNING)
98 _LOGGER.addHandler(logging_handler) 125 _LOGGER.addHandler(logging_handler)
99 126
100 if sys.platform.startswith('linux'): 127 if sys.platform.startswith('linux'):
101 logging.getLogger('procfs').setLevel(logging.WARNING) 128 logging.getLogger('procfs').setLevel(logging.WARNING)
102 logging.getLogger('procfs').addHandler(logging_handler) 129 logging.getLogger('procfs').addHandler(logging_handler)
103 pids = list_pids(argv) 130 pids = list_pids(argv)
104 pageframes = count_pageframes(pids) 131 pageframes = count_pageframes(pids)
105 else: 132 else:
106 _LOGGER.error('%s is not supported.' % sys.platform) 133 _LOGGER.error('%s is not supported.' % sys.platform)
107 return 1 134 return 1
108 135
109 # TODO(dmikurube): Classify this total RSS. 136 # TODO(dmikurube): Classify this total RSS.
110 print len(pageframes) * 4096 137 print len(pageframes) * 4096
111 138
112 return 0 139 return 0
113 140
114 141
115 if __name__ == '__main__': 142 if __name__ == '__main__':
116 sys.exit(main(sys.argv)) 143 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698