1cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci#!/usr/bin/env python 2cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# 3cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# Copyright (C) 2013 The Android Open Source Project 4cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# 5cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# Licensed under the Apache License, Version 2.0 (the "License"); 6cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# you may not use this file except in compliance with the License. 7cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# You may obtain a copy of the License at 8cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# 9cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# http://www.apache.org/licenses/LICENSE-2.0 10cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# 11cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# Unless required by applicable law or agreed to in writing, software 12cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# distributed under the License is distributed on an "AS IS" BASIS, 13cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# See the License for the specific language governing permissions and 15cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci# limitations under the License. 16cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 17cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci"""WebView postprocessor for the go/memdump tool. 18cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 19cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano TucciProcesses the output of memdump (see go/memdump) aggregating memory usage 20cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucciinformation for WebView analysis (both classic and chromium). 21cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 22cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano TucciUsage: adb shell /path/to/target/memdump <target-PID> | ./memreport.py > out.csv 23cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci""" 24cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 25cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 26cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucciimport os 27cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucciimport re 28cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucciimport sys 29cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 30cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tuccifrom sets import Set 31cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 32cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 33cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci_ENTRIES = [ 34cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci ('Total', '.* r... .*'), 35cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Read-only', '.* r--. .*'), 36cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Read-write', '.* rw.. .*'), 37cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Read-write (no x)', '.* rw-. .*'), 38cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Executable', '.* ..x. .*'), 39cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci ('Anonymous total', '.* .... .* .*shared_other=[0-9]+ ($|.*dlmalloc.*)'), 40cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Anonymous executable (JIT)', '.* ..x. .* shared_other=[0-9]+ ($|.*dlmalloc.*)'), 41cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Anonymous read-write', '.* rw.. .* .*shared_other=[0-9]+ ($|.*dlmalloc.*)'), 42cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Native heap (dlmalloc)', '.* r... .* /.*dlmalloc.*'), 43cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci ('File total', '.* .... .* /((?!dev/ashmem/dlmalloc).*)'), 44cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' File executable', '.* ..x. .* /((?!dev/ashmem/dlmalloc).*)'), 45cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' File read-write', '.* rw.. .* /((?!dev/ashmem/dlmalloc).*)'), 46cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Dalvik', '.* rw.. .* /.*dalvik.*'), 47cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Dalvik heap', '.* rw.. .* /.*dalvik-heap.*'), 48cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Ashmem', '.* rw.. .* /dev/ashmem .*'), 49cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebcore.so total', '.* r... .* /.*libwebcore.so'), 50cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebcore.so read-only', '.* r--. .* /.*libwebcore.so'), 51cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebcore.so read-write', '.* rw-. .* /.*libwebcore.so'), 52cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebcore.so executable', '.* r.x. .* /.*libwebcore.so'), 53cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebviewchromium.so total', '.* r... .* /.*libwebviewchromium.so'), 54cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebviewchromium.so read-only', '.* r--. .* /.*libwebviewchromium.so'), 55cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebviewchromium.so read-write', '.* rw-. .* /.*libwebviewchromium.so'), 56cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' libwebviewchromium.so executable', '.* r.x. .* /.*libwebviewchromium.so'), 57cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' Driver mappings', '.* .... .* /dev/\w+$'), 58cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' /dev/maliN total', '.* .... .* /dev/mali.*'), 59cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci ('OTHER (non file non anon)', '.* .... .*shared_other=[0-9]+ [^/]+'), 60cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci (' DMA buffers', '.* .... .*shared_other=[0-9]+ .*dmabuf.*'), 61cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci ] 62cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 63cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 64cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tuccidef _CollectMemoryStats(memdump, region_filters): 65cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci processes = [] 66cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci mem_usage_for_regions = None 67cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci regexps = {} 68cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for region_filter in region_filters: 69cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci regexps[region_filter] = re.compile(region_filter) 70cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for line in memdump: 71cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if 'PID=' in line: 72cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci mem_usage_for_regions = {} 73cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci processes.append(mem_usage_for_regions) 74cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci continue 75cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci matched_regions = Set([]) 76cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for region_filter in region_filters: 77cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if regexps[region_filter].match(line.rstrip('\r\n')): 78cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci matched_regions.add(region_filter) 79cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if not region_filter in mem_usage_for_regions: 80cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci mem_usage_for_regions[region_filter] = { 81cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 'private_unevictable': 0, 82cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 'private': 0, 83cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 'shared_app': 0.0, 84cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 'shared_other_unevictable': 0, 85cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 'shared_other': 0, 86cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci } 87cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for matched_region in matched_regions: 88cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci mem_usage = mem_usage_for_regions[matched_region] 89cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for key in mem_usage: 90cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for token in line.split(' '): 91cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if (key+'=') in token: 92cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci field = token.split('=')[1] 93cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if key != 'shared_app': 94cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci mem_usage[key] += int(field) 95cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci else: # shared_app=[\d,\d...] 96cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci array = eval(field) 97cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for i in xrange(len(array)): 98cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci mem_usage[key] += float(array[i]) / (i + 2) 99cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci break 100cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci return processes 101cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 102cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 103cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tuccidef _ConvertMemoryField(field): 104cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci return str(field / (1024)) 105cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 106cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 107cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tuccidef _DumpCSV(processes_stats): 108cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci total_map = {} 109cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci i = 0 110cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for process in processes_stats: 111cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci i += 1 112cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci print ',private,private_unevictable,shared_other,shared_other_unevictable,' 113cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci for (k, v) in _ENTRIES: 114cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci header_column = k + ',' if 'NOHEADER' not in os.environ else ',' 115cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if not v in process: 116cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci print header_column + '0,0,0,0,' 117cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci continue 118cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci if not v in total_map: 119cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci total_map[v] = 0 120cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci total_map[v] += process[v]['private'] + process[v]['shared_app'] 121cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci print ( 122cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci header_column + 123cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci _ConvertMemoryField(process[v]['private']) + ',' + 124cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci _ConvertMemoryField(process[v]['private_unevictable']) + ',' + 125cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci _ConvertMemoryField(process[v]['shared_other']) + ',' + 126cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci _ConvertMemoryField(process[v]['shared_other_unevictable']) + ',' 127cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci ) 128cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 129cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 130cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tuccidef main(argv): 131cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci _DumpCSV(_CollectMemoryStats(sys.stdin, [value for (key, value) in _ENTRIES])) 132cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 133cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci 134cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucciif __name__ == '__main__': 135cea1472db7958488e2fe7822250f4d1eba6cfd2cPrimiano Tucci main(sys.argv) 136