• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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