1""" 2OProfile is a system-wide profiler for Linux systems, 3capable of profiling all running code at low overhead. 4OProfile is released under the GNU GPL. 5 6It consists of a kernel driver and a daemon for collecting sample data, 7and several post-profiling tools for turning data into information. 8 9More Info: http://oprofile.sourceforge.net/ 10Will need some libaries to compile. Do 'apt-get build-dep oprofile' 11""" 12import os, shutil, time 13from autotest_lib.client.bin import utils, profiler 14from autotest_lib.client.common_lib import error 15import logging 16 17class oprofile(profiler.profiler): 18 version = 7 19 setup_done = False 20 21# Notes on whether to use the local copy or the builtin from source: 22# local = None 23# Try to use source copy if it works, else use local 24# local = False 25# Force use of the source copy 26# local = True 27# Force use of the local copy 28 29# http://prdownloads.sourceforge.net/oprofile/oprofile-0.9.4.tar.gz 30 def setup(self, tarball='oprofile-0.9.4.tar.bz2', local=None, 31 *args, **dargs): 32 if local == True: 33 return 34 35 try: 36 self.tarball = utils.unmap_url(self.bindir, tarball, 37 self.tmpdir) 38 utils.extract_tarball_to_dir(self.tarball, self.srcdir) 39 os.chdir(self.srcdir) 40 41 patch = os.path.join(self.bindir,"oprofile-69455.patch") 42 utils.system('patch -p1 < %s' % patch) 43 utils.configure('--with-kernel-support --prefix=' + \ 44 self.srcdir) 45 utils.make('-j %d' % utils.count_cpus()) 46 utils.make('install') 47 except: 48 # Build from source failed. 49 # But maybe can still use the local copy 50 local_opcontrol = os.path.exists('/usr/bin/opcontrol') 51 local_opreport = os.path.exists('/usr/bin/opreport') 52 if local == False or not local_opcontrol or not local_opreport: 53 raise error.AutotestError('No oprofile available') 54 else: 55 # if we managed to build, try again to pick binaries 56 self._pick_binaries(True) 57 58 59 def _setup_oprofile(self): 60 setup = ' --setup' 61 if not self.vmlinux: 62 setup += ' --no-vmlinux' 63 else: 64 setup += ' --vmlinux=%s' % self.vmlinux 65 for e in self.events: 66 setup += ' --event=%s' % e 67 if self.others: 68 setup += ' ' + self.others 69 70 71 utils.system(self.opcontrol + setup) 72 self.setup_done = True 73 74 75 def _pick_binaries(self, after_setup): 76 src_opreport = os.path.join(self.srcdir, 'bin/opreport') 77 src_opcontrol = os.path.join(self.srcdir, 'bin/opcontrol') 78 79 if (self.local == False and after_setup) or ( 80 (self.local in (None, False) and os.path.exists(src_opreport) 81 and os.path.exists(src_opcontrol))): 82 print "Using source-built copy of oprofile" 83 self.opreport = src_opreport 84 self.opcontrol = src_opcontrol 85 perform_setup = True 86 elif not self.local and not after_setup: 87 # if we are neither forced to use the local versions and 88 # we're not running after setup() then delay the decision 89 return 90 else: 91 print "Using machine local copy of oprofile" 92 self.opreport = '/usr/bin/opreport' 93 self.opcontrol = '/usr/bin/opcontrol' 94 95 self._setup_oprofile() 96 97 98 def initialize(self, vmlinux=None, events=[], others=None, local=None): 99 self.job.require_gcc() 100 101 if not vmlinux: 102 self.vmlinux = utils.get_vmlinux() 103 else: 104 self.vmlinux = vmlinux 105 if not len(events): 106 self.events = ['default'] 107 else: 108 self.events = events 109 self.others = others 110 self.local = local 111 112 # If there is existing setup file, oprofile may fail to start with default parameters. 113 if os.path.isfile('/root/.oprofile/daemonrc'): 114 os.rename('/root/.oprofile/daemonrc', '/root/.oprofile/daemonrc.org') 115 116 self._pick_binaries(False) 117 118 119 def start(self, test): 120 if not self.setup_done: 121 self._pick_binaries(True) 122 123 self.start_time = time.ctime() 124 utils.system(self.opcontrol + ' --shutdown') 125 utils.system(self.opcontrol + ' --reset') 126 utils.system(self.opcontrol + ' --start') 127 128 129 def stop(self, test): 130 self.stop_time = time.ctime() 131 utils.system(self.opcontrol + ' --stop') 132 utils.system(self.opcontrol + ' --dump') 133 134 135 def report(self, test): 136 # Output kernel per-symbol profile report 137 reportfile = test.profdir + '/oprofile.kernel' 138 if self.vmlinux: 139 report = self.opreport + ' -l ' + self.vmlinux 140 if os.path.exists(utils.get_modules_dir()): 141 report += ' -p ' + utils.get_modules_dir() 142 logging.info('Starting oprofile: %s' % self.start_time) 143 utils.system(report + ' > ' + reportfile) 144 logging.info('Ending oprofile: %s' % self.stop_time) 145 146 else: 147 utils.system("echo 'no vmlinux found.' > %s" % reportfile) 148 149 # output profile summary report 150 reportfile = test.profdir + '/oprofile.user' 151 logging.info('Starting oprofile: %s' % self.start_time) 152 utils.system(self.opreport + ' --long-filenames ' + ' >> ' + reportfile) 153 logging.info('Ending oprofile: %s' % self.stop_time) 154 155 utils.system(self.opcontrol + ' --shutdown') 156