blob: afefe7109fbe863f1c87baa1c89c2dfa941c5668 [file] [log] [blame]
Jeff Brown87866d92011-02-02 13:27:17 -08001#!/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)