command_line.py revision a02191e04bc25c4935f804f2c080ae28663d096d
1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Command line frontend for Memory Inspector""" 6 7import memory_inspector 8import optparse 9import time 10 11from memory_inspector.core import backends 12 13 14def main(argv): 15 usage = '%prog [options] devices | ps | stats' 16 parser = optparse.OptionParser(usage=usage) 17 parser.add_option('-b', '--backend', help='Backend name ' 18 '(e.g., Android)', type='string', default='Android') 19 parser.add_option('-s', '--device_id', help='Device ' 20 'id (e.g., Android serial)', type='string') 21 parser.add_option('-p', '--process_id', help='Target process id', 22 type='int') 23 parser.add_option('-m', '--filter_process_name', help='Process ' 24 'name to match', type='string') 25 (options, args) = parser.parse_args() 26 27 memory_inspector.RegisterAllBackends() 28 29 if not args: 30 parser.print_help() 31 return -1 32 if args[0] == 'devices': 33 _ListDevices(options.backend) 34 return 0 35 36 number_of_devices = 0 37 if options.device_id: 38 device_id = options.device_id 39 number_of_devices = 1 40 else: 41 for device in backends.ListDevices(): 42 if device.backend.name == options.backend: 43 number_of_devices += 1 44 device_id = device.id 45 46 if number_of_devices == 0: 47 print "No devices connected" 48 return -1 49 50 if number_of_devices > 1: 51 print ('More than 1 device connected. You need to provide' 52 ' --device_id') 53 return -1 54 55 if args[0] == 'ps': 56 _ListProcesses(options.backend, device_id, 57 options.filter_process_name) 58 return 0 59 60 if args[0] == 'stats': 61 if not options.process_id: 62 print 'You need to provide --process_id' 63 return -1 64 else: 65 _ListProcessStats(options.backend, device_id, 66 options.process_id) 67 return 0 68 else: 69 print 'Invalid command entered' 70 return -1 71 72 73def _ListDevices(backend_name): 74 print 'Device list:' 75 print '' 76 for device in backends.ListDevices(): 77 if device.backend.name == backend_name: 78 print '%-16s : %s' % (device.id, device.name) 79 80 81def _ListProcesses(backend_name, device_id, filter_process_name): 82 device = backends.GetDevice(backend_name, device_id) 83 if not device: 84 print 'Device', device_id, 'does not exist' 85 return 86 if not filter_process_name: 87 print 'Listing all processes' 88 else: 89 print 'Listing processes matching ' + filter_process_name.lower() 90 print '' 91 device.Initialize() 92 _PrintProcessHeadingLine() 93 for process in device.ListProcesses(): 94 if (not filter_process_name or 95 filter_process_name.lower() in process.name.lower()): 96 stats = process.GetStats() 97 _PrintProcess(process, stats) 98 99 100def _ListProcessStats(backend_name, device_id, process_id): 101 """Prints process stats periodically and displays an error if the 102 process or device does not exist. 103 """ 104 device = backends.GetDevice(backend_name, device_id) 105 if not device: 106 print 'Device', device_id, 'does not exist' 107 else: 108 device.Initialize() 109 process = device.GetProcess(process_id) 110 if not process: 111 print 'Cannot find process [%d] on device %s' % ( 112 process_id, device_id) 113 return 114 print 'Stats for process: [%d] %s' % (process_id, process.name) 115 _PrintProcessStatsHeadingLine() 116 while True: 117 stats = process.GetStats() 118 _PrintProcessStats(process, stats) 119 time.sleep(1) 120 121 122def _PrintProcessHeadingLine(): 123 print '%-10s : %-50s : %12s %12s %12s' % ( 124 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS','MEM_RSS_KB') 125 print '' 126 127 128def _PrintProcess(process, stats): 129 run_time_min, run_time_sec = divmod(stats.run_time, 60) 130 print '%10s : %-50s : %6s m %2s s %8s %12s' % ( 131 process.pid, process.name, run_time_min, run_time_sec, 132 stats.threads, stats.vm_rss) 133 134 135def _PrintProcessStatsHeadingLine(): 136 print '%-10s : %-50s : %12s %12s %13s %12s %14s' % ( 137 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS', 138 'CPU_USAGE', 'MEM_RSS_KB', 'PAGE_FAULTS') 139 print '' 140 141 142def _PrintProcessStats(process, stats): 143 run_time_min, run_time_sec = divmod(stats.run_time, 60) 144 print '%10s : %-50s : %6s m %2s s %8s %12s %13s %11s' % ( 145 process.pid, process.name, run_time_min, run_time_sec, 146 stats.threads, stats.cpu_usage, stats.vm_rss, stats.page_faults) 147 148 149