command_line.py revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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 elif args[0] == 'ps': 35 if not options.device_id: 36 print 'You need to specify a DEVICE' 37 return -1 38 else: 39 _ListProcesses(options.backend, options.device_id, 40 options.filter_process_name) 41 elif args[0] == 'stats': 42 if not options.device_id or not options.process_id: 43 print 'You need to specify a DEVICE-ID and PROCESS-ID' 44 return -1 45 else: 46 _ListProcessStats(options.backend, options.device_id, 47 options.process_id) 48 else: 49 print 'Invalid command entered' 50 return -1 51 print '' 52 53 54def _ListDevices(backend_name): 55 print 'Device list:' 56 print '' 57 for device in backends.ListDevices(): 58 if device.backend.name == backend_name: 59 print '%-16s : %s' % (device.id, device.name) 60 61 62def _ListProcesses(backend_name, device_id, filter_process_name): 63 device = backends.GetDevice(backend_name, device_id) 64 if not device: 65 print 'Device', device_id, 'does not exist' 66 else: 67 if not filter_process_name: 68 print 'Listing all processes' 69 else: 70 print 'Listing processes matching ' + filter_process_name.lower() 71 print '' 72 device.Initialize() 73 _PrintProcessStatsHeadingLine() 74 for process in device.ListProcesses(): 75 if (not filter_process_name or 76 filter_process_name.lower() in process.name.lower()): 77 stats = process.GetStats() 78 _PrintProcessStats(process, stats) 79 80 81def _ListProcessStats(backend_name, device_id, process_id): 82 """Prints process stats periodically and displays an error if the 83 process or device does not exist 84 """ 85 device = backends.GetDevice(backend_name, device_id) 86 if not device: 87 print 'Device', device_id, 'does not exist' 88 else: 89 device.Initialize() 90 process = device.GetProcess(process_id) 91 if not process: 92 print 'Cannot find process [%d] on device %s' % ( 93 process_id, device_id) 94 return 95 print 'Stats for process: [%d] %s' % (process_id, process.name) 96 _PrintProcessStatsHeadingLine() 97 while True: 98 stats = process.GetStats() 99 _PrintProcessStats(process, stats) 100 time.sleep(1) 101 102 103def _PrintProcessStatsHeadingLine(): 104 print '%-10s : %-50s : %12s %12s %13s %10s %14s' % ( 105 'Process ID', 'Process Name', 'RUN_TIME', 'THREADS', 106 'CPU_USAGE', 'MEM_RSS_KB', 'PAGE_FAULTS') 107 print '' 108 109 110def _PrintProcessStats(process, stats): 111 run_time_min, run_time_sec = divmod(stats.run_time, 60) 112 print '%10s : %-50s : %6s m %2s s %8s %12s %12s %11s' % ( 113 process.pid, process.name, run_time_min, run_time_sec, 114 stats.threads, stats.cpu_usage, stats.vm_rss, stats.page_faults) 115 116 117