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