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.
9 from telemetry
.core
import exceptions
10 from telemetry
.internal
.platform
import profiler
15 import pexpect
# pylint: disable=import-error
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
],
31 if self
._proc
.getecho():
32 output
= self
._proc
.readline().strip()
35 if 'iprofiler: Profiling process' in 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')
49 return self
._proc
.getecho()
50 py_utils
.WaitFor(Echo
, timeout
=5)
52 def CollectProfile(self
):
53 self
._proc
.kill(signal
.SIGINT
)
56 except pexpect
.ExceptionPexpect
:
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
78 self
._process
_profilers
.append(
79 _SingleProcessIprofilerProfiler(pid
, output_file
))
86 def is_supported(cls
, browser_type
):
87 if sys
.platform
!= 'darwin':
89 if browser_type
== 'any':
91 return (not browser_type
.startswith('android') and
92 not browser_type
.startswith('cros'))
94 def CollectProfile(self
):
96 for single_process
in self
._process
_profilers
:
97 output_files
.append(single_process
.CollectProfile())