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