diff options
author | paulwhitton@google.com <paulwhitton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-23 15:54:41 +0000 |
---|---|---|
committer | paulwhitton@google.com <paulwhitton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-23 15:54:41 +0000 |
commit | 9f0c7f57f2ccbf6db1bc32c57441761924f8d59e (patch) | |
tree | db128f5edcb0c3aeb34f3fabab1a7567c67b7e3f /tools/memory_inspector | |
parent | 27d0c1c519ee887f7dccf61942d05c5929777476 (diff) | |
download | chromium_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.py | 168 | ||||
-rwxr-xr-x | tools/memory_inspector/memory_inspector_cli | 2 |
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()) |