Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / telemetry / internal / platform / profiler / iprofiler_profiler.py
blobbf57427a6975706a9633ff6e10320bae794a830d
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import os
6 import signal
7 import sys
9 from telemetry.core import exceptions
10 from telemetry.internal.platform import profiler
12 import py_utils
14 try:
15 import pexpect # pylint: disable=import-error
16 except ImportError:
17 pass
20 class _SingleProcessIprofilerProfiler(object):
21 """An internal class for using iprofiler for a given process."""
22 def __init__(self, pid, output_path):
23 self._output_path = output_path
24 output_dir = os.path.dirname(self._output_path)
25 output_file = os.path.basename(self._output_path)
26 self._proc = pexpect.spawn(
27 'iprofiler', ['-timeprofiler', '-T', '300', '-a', str(pid),
28 '-d', output_dir, '-o', output_file],
29 timeout=300)
30 while True:
31 if self._proc.getecho():
32 output = self._proc.readline().strip()
33 if not output:
34 continue
35 if 'iprofiler: Profiling process' in output:
36 break
37 print output
38 self._proc.interact(escape_character='\x0d')
39 if 'Failed to authorize rights' in output:
40 raise exceptions.ProfilingException(
41 'Failed to authorize rights for iprofiler\n')
42 if 'iprofiler error' in output:
43 raise exceptions.ProfilingException(
44 'Failed to start iprofiler for process %s\n' %
45 self._output_path.split('.')[1])
46 self._proc.write('\x0d')
47 print
48 def Echo():
49 return self._proc.getecho()
50 py_utils.WaitFor(Echo, timeout=5)
52 def CollectProfile(self):
53 self._proc.kill(signal.SIGINT)
54 try:
55 self._proc.wait()
56 except pexpect.ExceptionPexpect:
57 pass
58 finally:
59 self._proc = None
61 print 'To view the profile, run:'
62 print ' open -a Instruments %s.dtps' % self._output_path
63 return self._output_path
66 class IprofilerProfiler(profiler.Profiler):
68 def __init__(self, browser_backend, platform_backend, output_path, state):
69 super(IprofilerProfiler, self).__init__(
70 browser_backend, platform_backend, output_path, state)
71 process_output_file_map = self._GetProcessOutputFileMap()
72 self._process_profilers = []
73 for pid, output_file in process_output_file_map.iteritems():
74 if '.utility' in output_file:
75 # The utility process may not have been started by Telemetry.
76 # So we won't have permissing to profile it
77 continue
78 self._process_profilers.append(
79 _SingleProcessIprofilerProfiler(pid, output_file))
81 @classmethod
82 def name(cls):
83 return 'iprofiler'
85 @classmethod
86 def is_supported(cls, browser_type):
87 if sys.platform != 'darwin':
88 return False
89 if browser_type == 'any':
90 return True
91 return (not browser_type.startswith('android') and
92 not browser_type.startswith('cros'))
94 def CollectProfile(self):
95 output_files = []
96 for single_process in self._process_profilers:
97 output_files.append(single_process.CollectProfile())
98 return output_files