summaryrefslogtreecommitdiffstats
path: root/tools/memory_inspector
diff options
context:
space:
mode:
authorpaulwhitton@google.com <paulwhitton@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-23 15:54:41 +0000
committerpaulwhitton@google.com <paulwhitton@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-23 15:54:41 +0000
commit9f0c7f57f2ccbf6db1bc32c57441761924f8d59e (patch)
treedb128f5edcb0c3aeb34f3fabab1a7567c67b7e3f /tools/memory_inspector
parent27d0c1c519ee887f7dccf61942d05c5929777476 (diff)
downloadchromium_src-9f0c7f57f2ccbf6db1bc32c57441761924f8d59e.zip
chromium_src-9f0c7f57f2ccbf6db1bc32c57441761924f8d59e.tar.gz
chromium_src-9f0c7f57f2ccbf6db1bc32c57441761924f8d59e.tar.bz2
Further enhancements to command_line frontend to memory_inspector
Print memory maps for a process Print consolidated memory map data for a process BUG=340294 NOTRY=true Review URL: https://codereview.chromium.org/240023003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@265655 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/memory_inspector')
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/command_line.py168
-rwxr-xr-xtools/memory_inspector/memory_inspector_cli2
2 files changed, 95 insertions, 75 deletions
diff --git a/tools/memory_inspector/memory_inspector/frontends/command_line.py b/tools/memory_inspector/memory_inspector/frontends/command_line.py
index d85a2c7..cfcb7c8 100644
--- a/tools/memory_inspector/memory_inspector/frontends/command_line.py
+++ b/tools/memory_inspector/memory_inspector/frontends/command_line.py
@@ -4,15 +4,20 @@
"""Command line frontend for Memory Inspector"""
+import json
import memory_inspector
import optparse
+import os
import time
+from memory_inspector.classification import mmap_classifier
from memory_inspector.core import backends
+from memory_inspector.data import serialization
-def main(argv):
- usage = '%prog [options] devices | ps | stats'
+def main():
+ COMMANDS = ['devices', 'ps', 'stats', 'mmaps', 'classified_mmaps']
+ usage = ('%prog [options] ' + ' | '.join(COMMANDS))
parser = optparse.OptionParser(usage=usage)
parser.add_option('-b', '--backend', help='Backend name '
'(e.g., Android)', type='string', default='Android')
@@ -22,13 +27,18 @@ def main(argv):
type='int')
parser.add_option('-m', '--filter_process_name', help='Process '
'name to match', type='string')
+ parser.add_option('-r', '--mmap_rule',
+ help='mmap rule', type='string',
+ default=
+ 'classification_rules/default/mmap-android.py')
(options, args) = parser.parse_args()
memory_inspector.RegisterAllBackends()
- if not args:
+ if not args or args[0] not in COMMANDS:
parser.print_help()
return -1
+
if args[0] == 'devices':
_ListDevices(options.backend)
return 0
@@ -52,23 +62,53 @@ def main(argv):
' --device_id')
return -1
- if args[0] == 'ps':
- _ListProcesses(options.backend, device_id,
- options.filter_process_name)
- return 0
+ device = backends.GetDevice(options.backend, device_id)
+ if not device:
+ print 'Device', device_id, 'does not exist'
+ return -1
- if args[0] == 'stats':
- if not options.process_id:
- print 'You need to provide --process_id'
- return -1
+ device.Initialize()
+ if args[0] == 'ps':
+ if not options.filter_process_name:
+ print 'Listing all processes'
else:
- _ListProcessStats(options.backend, device_id,
- options.process_id)
+ print ('Listing processes matching '
+ + options.filter_process_name.lower())
+ print ''
+ print '%-10s : %-50s : %12s %12s %12s' % (
+ 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS',
+ 'MEM_RSS_KB')
+ print ''
+ for process in device.ListProcesses():
+ if (not options.filter_process_name or
+ options.filter_process_name.lower() in process.name.lower()):
+ stats = process.GetStats()
+ run_time_min, run_time_sec = divmod(stats.run_time, 60)
+ print '%10s : %-50s : %6s m %2s s %8s %12s' % (
+ process.pid, process.name, run_time_min, run_time_sec,
+ stats.threads, stats.vm_rss)
return 0
- else:
- print 'Invalid command entered'
+
+ if not options.process_id:
+ print 'You need to provide --process_id'
return -1
+ process = device.GetProcess(options.process_id)
+
+ if not process:
+ print 'Cannot find process [%d] on device %s' % (
+ options.process_id, device.id)
+ return -1
+ elif args[0] == 'stats':
+ _ListProcessStats(process)
+ return 0
+ elif args[0] == 'mmaps':
+ _ListProcessMmaps(process)
+ return 0
+ elif args[0] == 'classified_mmaps':
+ _ListProcessClassifiedMmaps(process, options.mmap_rule)
+ return 0
+
def _ListDevices(backend_name):
print 'Device list:'
@@ -78,71 +118,51 @@ def _ListDevices(backend_name):
print '%-16s : %s' % (device.id, device.name)
-def _ListProcesses(backend_name, device_id, filter_process_name):
- device = backends.GetDevice(backend_name, device_id)
- if not device:
- print 'Device', device_id, 'does not exist'
- return
- if not filter_process_name:
- print 'Listing all processes'
- else:
- print 'Listing processes matching ' + filter_process_name.lower()
- print ''
- device.Initialize()
- _PrintProcessHeadingLine()
- for process in device.ListProcesses():
- if (not filter_process_name or
- filter_process_name.lower() in process.name.lower()):
- stats = process.GetStats()
- _PrintProcess(process, stats)
-
-
-def _ListProcessStats(backend_name, device_id, process_id):
- """Prints process stats periodically and displays an error if the
- process or device does not exist.
+def _ListProcessStats(process):
+ """Prints process stats periodically
"""
- device = backends.GetDevice(backend_name, device_id)
- if not device:
- print 'Device', device_id, 'does not exist'
- else:
- device.Initialize()
- process = device.GetProcess(process_id)
- if not process:
- print 'Cannot find process [%d] on device %s' % (
- process_id, device_id)
- return
- print 'Stats for process: [%d] %s' % (process_id, process.name)
- _PrintProcessStatsHeadingLine()
- while True:
- stats = process.GetStats()
- _PrintProcessStats(process, stats)
- time.sleep(1)
-
-
-def _PrintProcessHeadingLine():
- print '%-10s : %-50s : %12s %12s %12s' % (
- 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS','MEM_RSS_KB')
+ print 'Stats for process: [%d] %s' % (process.pid, process.name)
+ print '%-10s : %-50s : %12s %12s %13s %12s %14s' % (
+ 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS',
+ 'CPU_USAGE', 'MEM_RSS_KB', 'PAGE_FAULTS')
print ''
+ while True:
+ stats = process.GetStats()
+ run_time_min, run_time_sec = divmod(stats.run_time, 60)
+ print '%10s : %-50s : %6s m %2s s %8s %12s %13s %11s' % (
+ process.pid, process.name, run_time_min, run_time_sec,
+ stats.threads, stats.cpu_usage, stats.vm_rss, stats.page_faults)
+ time.sleep(1)
-def _PrintProcess(process, stats):
- run_time_min, run_time_sec = divmod(stats.run_time, 60)
- print '%10s : %-50s : %6s m %2s s %8s %12s' % (
- process.pid, process.name, run_time_min, run_time_sec,
- stats.threads, stats.vm_rss)
-
-
-def _PrintProcessStatsHeadingLine():
- print '%-10s : %-50s : %12s %12s %13s %12s %14s' % (
- 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS',
- 'CPU_USAGE', 'MEM_RSS_KB', 'PAGE_FAULTS')
+def _ListProcessMmaps(process):
+ """Prints process memory maps
+ """
+ print 'Memory Maps for process: [%d] %s' % (process.pid, process.name)
+ print '%-10s %-10s %6s %12s %12s %13s %13s %-40s' % (
+ 'START', 'END', 'FLAGS', 'PRIV.DIRTY', 'PRIV.CLEAN',
+ 'SHARED DIRTY', 'SHARED CLEAN', 'MAPPED_FILE')
+ print '%38s %12s %12s %13s' % ('(kb)', '(kb)', '(kb)', '(kb)')
print ''
+ maps = process.DumpMemoryMaps()
+ for entry in maps.entries:
+ print '%-10x %-10x %6s %12s %12s %13s %13s %-40s' % (
+ entry.start, entry.end, entry.prot_flags,
+ entry.priv_dirty_bytes / 1024, entry.priv_clean_bytes / 1024,
+ entry.shared_dirty_bytes / 1024,
+ entry.shared_clean_bytes / 1024, entry.mapped_file)
-def _PrintProcessStats(process, stats):
- run_time_min, run_time_sec = divmod(stats.run_time, 60)
- print '%10s : %-50s : %6s m %2s s %8s %12s %13s %11s' % (
- process.pid, process.name, run_time_min, run_time_sec,
- stats.threads, stats.cpu_usage, stats.vm_rss, stats.page_faults)
+def _ListProcessClassifiedMmaps(process, mmap_rule):
+ """Prints process classified memory maps
+ """
+ maps = process.DumpMemoryMaps()
+ if not os.path.exists(mmap_rule):
+ print 'File', mmap_rule, 'not found'
+ return
+ with open(mmap_rule) as f:
+ rules = mmap_classifier.LoadRules(f.read())
+ classified_results_tree = mmap_classifier.Classify(maps, rules)
+ print json.dumps(classified_results_tree, cls=serialization.Encoder)
diff --git a/tools/memory_inspector/memory_inspector_cli b/tools/memory_inspector/memory_inspector_cli
index ead2754..774a50f 100755
--- a/tools/memory_inspector/memory_inspector_cli
+++ b/tools/memory_inspector/memory_inspector_cli
@@ -11,4 +11,4 @@ from memory_inspector.frontends import command_line
if __name__ == '__main__':
- sys.exit(command_line.main(sys.argv))
+ sys.exit(command_line.main())