"""
OProfile is a system-wide profiler for Linux systems,
capable of profiling all running code at low overhead.
OProfile is released under the GNU GPL.
It consists of a kernel driver and a daemon for collecting sample data,
and several post-profiling tools for turning data into information.
More Info: http://oprofile.sourceforge.net/
Will need some libaries to compile. Do 'apt-get build-dep oprofile'
"""
import os, shutil, time
from autotest_lib.client.bin import utils, profiler
from autotest_lib.client.common_lib import error
import logging
class oprofile(profiler.profiler):
version = 7
setup_done = False
# Notes on whether to use the local copy or the builtin from source:
# local = None
# Try to use source copy if it works, else use local
# local = False
# Force use of the source copy
# local = True
# Force use of the local copy
# http://prdownloads.sourceforge.net/oprofile/oprofile-0.9.4.tar.gz
def setup(self, tarball='oprofile-0.9.4.tar.bz2', local=None,
*args, **dargs):
if local == True:
return
try:
self.tarball = utils.unmap_url(self.bindir, tarball,
self.tmpdir)
utils.extract_tarball_to_dir(self.tarball, self.srcdir)
os.chdir(self.srcdir)
patch = os.path.join(self.bindir,"oprofile-69455.patch")
utils.system('patch -p1 < %s' % patch)
utils.configure('--with-kernel-support --prefix=' + \
self.srcdir)
utils.make('-j %d' % utils.count_cpus())
utils.make('install')
except:
# Build from source failed.
# But maybe can still use the local copy
local_opcontrol = os.path.exists('/usr/bin/opcontrol')
local_opreport = os.path.exists('/usr/bin/opreport')
if local == False or not local_opcontrol or not local_opreport:
raise error.AutotestError('No oprofile available')
else:
# if we managed to build, try again to pick binaries
self._pick_binaries(True)
def _setup_oprofile(self):
setup = ' --setup'
if not self.vmlinux:
setup += ' --no-vmlinux'
else:
setup += ' --vmlinux=%s' % self.vmlinux
for e in self.events:
setup += ' --event=%s' % e
if self.others:
setup += ' ' + self.others
utils.system(self.opcontrol + setup)
self.setup_done = True
def _pick_binaries(self, after_setup):
src_opreport = os.path.join(self.srcdir, 'bin/opreport')
src_opcontrol = os.path.join(self.srcdir, 'bin/opcontrol')
if (self.local == False and after_setup) or (
(self.local in (None, False) and os.path.exists(src_opreport)
and os.path.exists(src_opcontrol))):
print "Using source-built copy of oprofile"
self.opreport = src_opreport
self.opcontrol = src_opcontrol
perform_setup = True
elif not self.local and not after_setup:
# if we are neither forced to use the local versions and
# we're not running after setup() then delay the decision
return
else:
print "Using machine local copy of oprofile"
self.opreport = '/usr/bin/opreport'
self.opcontrol = '/usr/bin/opcontrol'
self._setup_oprofile()
def initialize(self, vmlinux=None, events=[], others=None, local=None):
self.job.require_gcc()
if not vmlinux:
self.vmlinux = utils.get_vmlinux()
else:
self.vmlinux = vmlinux
if not len(events):
self.events = ['default']
else:
self.events = events
self.others = others
self.local = local
# If there is existing setup file, oprofile may fail to start with default parameters.
if os.path.isfile('/root/.oprofile/daemonrc'):
os.rename('/root/.oprofile/daemonrc', '/root/.oprofile/daemonrc.org')
self._pick_binaries(False)
def start(self, test):
if not self.setup_done:
self._pick_binaries(True)
self.start_time = time.ctime()
utils.system(self.opcontrol + ' --shutdown')
utils.system(self.opcontrol + ' --reset')
utils.system(self.opcontrol + ' --start')
def stop(self, test):
self.stop_time = time.ctime()
utils.system(self.opcontrol + ' --stop')
utils.system(self.opcontrol + ' --dump')
def report(self, test):
# Output kernel per-symbol profile report
reportfile = test.profdir + '/oprofile.kernel'
if self.vmlinux:
report = self.opreport + ' -l ' + self.vmlinux
if os.path.exists(utils.get_modules_dir()):
report += ' -p ' + utils.get_modules_dir()
logging.info('Starting oprofile: %s' % self.start_time)
utils.system(report + ' > ' + reportfile)
logging.info('Ending oprofile: %s' % self.stop_time)
else:
utils.system("echo 'no vmlinux found.' > %s" % reportfile)
# output profile summary report
reportfile = test.profdir + '/oprofile.user'
logging.info('Starting oprofile: %s' % self.start_time)
utils.system(self.opreport + ' --long-filenames ' + ' >> ' + reportfile)
logging.info('Ending oprofile: %s' % self.stop_time)
utils.system(self.opcontrol + ' --shutdown')