| OLD | NEW |
| 1 # Copyright (C) 2012 Google Inc. All rights reserved. | 1 # Copyright (C) 2012 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | 28 |
| 29 import logging | 29 import logging |
| 30 import re | 30 import re |
| 31 import itertools | 31 import itertools |
| 32 | 32 |
| 33 _log = logging.getLogger(__name__) | 33 _log = logging.getLogger(__name__) |
| 34 | 34 |
| 35 | 35 |
| 36 class ProfilerFactory(object): | 36 class ProfilerFactory(object): |
| 37 |
| 37 @classmethod | 38 @classmethod |
| 38 def create_profiler(cls, host, executable_path, output_dir, profiler_name=No
ne, identifier=None): | 39 def create_profiler(cls, host, executable_path, output_dir, profiler_name=No
ne, identifier=None): |
| 39 profilers = cls.profilers_for_platform(host.platform) | 40 profilers = cls.profilers_for_platform(host.platform) |
| 40 if not profilers: | 41 if not profilers: |
| 41 return None | 42 return None |
| 42 profiler_name = profiler_name or cls.default_profiler_name(host.platform
) | 43 profiler_name = profiler_name or cls.default_profiler_name(host.platform
) |
| 43 profiler_class = next(itertools.ifilter(lambda profiler: profiler.name =
= profiler_name, profilers), None) | 44 profiler_class = next(itertools.ifilter(lambda profiler: profiler.name =
= profiler_name, profilers), None) |
| 44 if not profiler_class: | 45 if not profiler_class: |
| 45 return None | 46 return None |
| 46 return profilers[0](host, executable_path, output_dir, identifier) | 47 return profilers[0](host, executable_path, output_dir, identifier) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 77 return env | 78 return env |
| 78 | 79 |
| 79 def attach_to_pid(self, pid): | 80 def attach_to_pid(self, pid): |
| 80 pass | 81 pass |
| 81 | 82 |
| 82 def profile_after_exit(self): | 83 def profile_after_exit(self): |
| 83 pass | 84 pass |
| 84 | 85 |
| 85 | 86 |
| 86 class SingleFileOutputProfiler(Profiler): | 87 class SingleFileOutputProfiler(Profiler): |
| 88 |
| 87 def __init__(self, host, executable_path, output_dir, output_suffix, identif
ier=None): | 89 def __init__(self, host, executable_path, output_dir, output_suffix, identif
ier=None): |
| 88 super(SingleFileOutputProfiler, self).__init__(host, executable_path, ou
tput_dir, identifier) | 90 super(SingleFileOutputProfiler, self).__init__(host, executable_path, ou
tput_dir, identifier) |
| 89 # FIXME: Currently all reports are kept as test.*, until we fix that, se
arch up to 1000 names before giving up. | 91 # FIXME: Currently all reports are kept as test.*, until we fix that, se
arch up to 1000 names before giving up. |
| 90 self._output_path = self._host.workspace.find_unused_filename(self._outp
ut_dir, self._identifier, output_suffix, search_limit=1000) | 92 self._output_path = self._host.workspace.find_unused_filename( |
| 93 self._output_dir, self._identifier, output_suffix, search_limit=1000
) |
| 91 assert(self._output_path) | 94 assert(self._output_path) |
| 92 | 95 |
| 93 | 96 |
| 94 class GooglePProf(SingleFileOutputProfiler): | 97 class GooglePProf(SingleFileOutputProfiler): |
| 95 name = 'pprof' | 98 name = 'pprof' |
| 96 | 99 |
| 97 def __init__(self, host, executable_path, output_dir, identifier=None): | 100 def __init__(self, host, executable_path, output_dir, identifier=None): |
| 98 super(GooglePProf, self).__init__(host, executable_path, output_dir, "pp
rof", identifier) | 101 super(GooglePProf, self).__init__(host, executable_path, output_dir, "pp
rof", identifier) |
| 99 | 102 |
| 100 def adjusted_environment(self, env): | 103 def adjusted_environment(self, env): |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 196 |
| 194 def __init__(self, host, executable_path, output_dir, identifier=None): | 197 def __init__(self, host, executable_path, output_dir, identifier=None): |
| 195 super(IProfiler, self).__init__(host, executable_path, output_dir, "dtps
", identifier) | 198 super(IProfiler, self).__init__(host, executable_path, output_dir, "dtps
", identifier) |
| 196 self._profiler_process = None | 199 self._profiler_process = None |
| 197 | 200 |
| 198 def attach_to_pid(self, pid): | 201 def attach_to_pid(self, pid): |
| 199 # FIXME: iprofiler requires us to pass the directory separately | 202 # FIXME: iprofiler requires us to pass the directory separately |
| 200 # from the basename of the file, with no control over the extension. | 203 # from the basename of the file, with no control over the extension. |
| 201 fs = self._host.filesystem | 204 fs = self._host.filesystem |
| 202 cmd = ["iprofiler", "-timeprofiler", "-a", pid, | 205 cmd = ["iprofiler", "-timeprofiler", "-a", pid, |
| 203 "-d", fs.dirname(self._output_path), "-o", fs.splitext(fs.basena
me(self._output_path))[0]] | 206 "-d", fs.dirname(self._output_path), "-o", fs.splitext(fs.basenam
e(self._output_path))[0]] |
| 204 # FIXME: Consider capturing instead of letting instruments spam to stder
r directly. | 207 # FIXME: Consider capturing instead of letting instruments spam to stder
r directly. |
| 205 self._profiler_process = self._host.executive.popen(cmd) | 208 self._profiler_process = self._host.executive.popen(cmd) |
| 206 | 209 |
| 207 def profile_after_exit(self): | 210 def profile_after_exit(self): |
| 208 # It seems like a nicer user experiance to wait on the profiler to exit
to prevent | 211 # It seems like a nicer user experiance to wait on the profiler to exit
to prevent |
| 209 # it from spewing to stderr at odd times. | 212 # it from spewing to stderr at odd times. |
| 210 self._profiler_process.wait() | 213 self._profiler_process.wait() |
| OLD | NEW |