blob: 3373b0cc778647c4095bdc7aacc77f788877d4b7 [file] [log] [blame]
#!/usr/bin/env python2.6
#
# Copyright (C) 2011 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Remotely controls an OProfile session on an Android device.
#
import os
import sys
import subprocess
import getopt
import re
class Adb:
def __init__(self, serial_number):
self._base_args = ['adb']
if serial_number != None:
self._base_args.append('-s')
self._base_args.append(serial_number)
def shell(self, command_args, echo=True):
print 'adb: %s' % (' '.join(command_args))
popen = subprocess.Popen(self._base_args + ['shell'] + command_args,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = ''
while True:
stdout, stderr = popen.communicate()
if echo:
print stdout
print stderr
output += stdout
output += stderr
rc = popen.poll()
if rc is not None:
break
print 'exit code: %d' % rc
return rc, output
class Tool:
def __init__(self, argv):
self.argv = argv
self.verbose = False
def usage(self):
print "Usage:" + self.argv[0]
print " -h, --help : show this help text"
print " -s, --serial=number : the serial number of the device being profiled"
print " -v, --verbose : show verbose output"
print " --setup : setup profiler"
print " --shutdown : shutdown profiler"
print " --start : start profiling"
print " --stop : stop profiling"
print " --status : show profiler status"
print
def main(self):
try:
opts, args = getopt.getopt(self.argv[1:],
"hs:v",
["help", "serial=", "setup", "start", "stop", "status", "shutdown", "verbose"])
except getopt.GetoptError, e:
self.usage()
print str(e)
return 1
serial_number = None
command = None
for o, a in opts:
if o in ('-h', '--help'):
self.usage()
return 0
elif o in ('-s', '--serial'):
serial_number = a
elif o in ('-v', '--verbose'):
self.verbose = True
elif o in ('--setup', '--start', '--stop', '--status', '--shutdown'):
command = o[2:]
else:
assert False, 'unhandled option' + o
self.adb = Adb(serial_number)
if command == 'setup':
rc = self.setup()
elif command == 'shutdown':
rc = self.shutdown()
elif command == 'start':
rc = self.start()
elif command == 'stop':
rc = self.stop()
elif command == 'status':
rc = self.status()
else:
self.usage()
print 'A command must be specified.'
rc = 1
return rc
def setup(self):
rc, output = self.adb.shell(['cat', '/proc/kallsyms'], echo=False)
if rc != 0:
print 'Failed to determine kernel VMA range.'
return rc
vma_start = re.search('([0-9a-fA-F]{8}) T _text', output).group(1)
vma_end = re.search('([0-9a-fA-F]{8}) A _etext', output).group(1)
rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [
'--reset',
'--kernel-range=' + vma_start + '-' + vma_end,
#'--event=CPU_CYCLES:100000',
'--timer',
'--setup',
'--status', '--verbose-log=all'])
def shutdown(self):
rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [
'--shutdown'])
if rc != 0:
print 'Failed to shutdown.'
return rc
return rc
def start(self):
rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [
'--start', '--status'])
return rc
def stop(self):
rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [
'--stop', '--status'])
return rc
def status(self):
rc, output = self.adb.shell(['/system/xbin/opcontrol'] + self.opcontrol_verbose() + [
'--status'])
return rc
def opcontrol_verbose(self):
if self.verbose:
return ['--verbose']
else:
return []
# Main entry point
tool = Tool(sys.argv)
rc = tool.main()
sys.exit(rc)