oprofile_android revision 87866d93bd7de46ffe9333437e5230c6eda58448
1#!/usr/bin/env python2.6 2# 3# Copyright (C) 2011 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18# 19# Remotely controls an OProfile session on an Android device. 20# 21 22import os 23import sys 24import subprocess 25import getopt 26import re 27 28 29class Adb: 30 def __init__(self, serial_number): 31 self._base_args = ['adb'] 32 if serial_number != None: 33 self._base_args.append('-s') 34 self._base_args.append(serial_number) 35 36 def shell(self, command_args, echo=True): 37 print 'adb: %s' % (' '.join(command_args)) 38 popen = subprocess.Popen(self._base_args + ['shell'] + command_args, 39 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 40 output = '' 41 while True: 42 stdout, stderr = popen.communicate() 43 if echo: 44 print stdout 45 print stderr 46 output += stdout 47 output += stderr 48 rc = popen.poll() 49 if rc is not None: 50 break 51 print 'exit code: %d' % rc 52 return rc, output 53 54 55class Tool: 56 def __init__(self, argv): 57 self.argv = argv 58 self.verbose = False 59 60 def usage(self): 61 print "Usage:" + self.argv[0] 62 print " -h, --help : show this help text" 63 print " -s, --serial=number : the serial number of the device being profiled" 64 print " -v, --verbose : show verbose output" 65 print " --setup : setup profiler" 66 print " --shutdown : shutdown profiler" 67 print " --start : start profiling" 68 print " --stop : stop profiling" 69 print " --status : show profiler status" 70 print 71 72 def main(self): 73 try: 74 opts, args = getopt.getopt(self.argv[1:], 75 "hs:v", 76 ["help", "serial=", "setup", "start", "stop", "status", "shutdown", "verbose"]) 77 except getopt.GetoptError, e: 78 self.usage() 79 print str(e) 80 return 1 81 82 serial_number = None 83 command = None 84 for o, a in opts: 85 if o in ('-h', '--help'): 86 self.usage() 87 return 0 88 elif o in ('-s', '--serial'): 89 serial_number = a 90 elif o in ('-v', '--verbose'): 91 self.verbose = True 92 elif o in ('--setup', '--start', '--stop', '--status', '--shutdown'): 93 command = o[2:] 94 else: 95 assert False, 'unhandled option' + o 96 97 self.adb = Adb(serial_number) 98 99 if command == 'setup': 100 rc = self.setup() 101 elif command == 'shutdown': 102 rc = self.shutdown() 103 elif command == 'start': 104 rc = self.start() 105 elif command == 'stop': 106 rc = self.stop() 107 elif command == 'status': 108 rc = self.status() 109 else: 110 self.usage() 111 print 'A command must be specified.' 112 rc = 1 113 return rc 114 115 def setup(self): 116 rc, output = self.adb.shell(['cat', '/proc/kallsyms'], echo=False) 117 if rc != 0: 118 print 'Failed to determine kernel VMA range.' 119 return rc 120 vma_start = re.search('([0-9a-fA-F]{8}) T _text', output).group(1) 121 vma_end = re.search('([0-9a-fA-F]{8}) A _etext', output).group(1) 122 123 rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [ 124 '--reset', 125 '--kernel-range=' + vma_start + '-' + vma_end, 126 '--event=CPU_CYCLES:100000', 127 '--setup', 128 '--status', '--verbose-log=all']) 129 130 def shutdown(self): 131 rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [ 132 '--shutdown']) 133 if rc != 0: 134 print 'Failed to shutdown.' 135 return rc 136 return rc 137 138 def start(self): 139 rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [ 140 '--start', '--status']) 141 return rc 142 143 def stop(self): 144 rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [ 145 '--stop', '--status']) 146 return rc 147 148 def status(self): 149 rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [ 150 '--status']) 151 return rc 152 153 def opcontrol_verbose(self): 154 if self.verbose: 155 return ['--verbose'] 156 else: 157 return [] 158 159# Main entry point 160tool = Tool(sys.argv) 161rc = tool.main() 162sys.exit(rc)