summaryrefslogtreecommitdiffstats
path: root/tools/telemetry
diff options
context:
space:
mode:
Diffstat (limited to 'tools/telemetry')
-rw-r--r--tools/telemetry/telemetry/core/platform/profiler/iprofiler_profiler.py65
-rw-r--r--tools/telemetry/telemetry/core/platform/profiler/profiler_finder.py6
-rw-r--r--tools/telemetry/telemetry/core/platform/profiler/sample_profiler.py58
3 files changed, 128 insertions, 1 deletions
diff --git a/tools/telemetry/telemetry/core/platform/profiler/iprofiler_profiler.py b/tools/telemetry/telemetry/core/platform/profiler/iprofiler_profiler.py
new file mode 100644
index 0000000..66ea97e
--- /dev/null
+++ b/tools/telemetry/telemetry/core/platform/profiler/iprofiler_profiler.py
@@ -0,0 +1,65 @@
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import signal
+import sys
+
+from telemetry.core import util
+from telemetry.core.platform import profiler
+
+# pexpect is not available on all platforms so use the third_party version.
+sys.path.append(os.path.join(
+ os.path.abspath(os.path.dirname(__file__)), '..', '..', '..', '..', '..',
+ '..', 'third_party', 'pexpect'))
+import pexpect # pylint: disable=F0401
+
+
+class IprofilerProfiler(profiler.Profiler):
+
+ def __init__(self, browser_backend, pid, output_path):
+ super(IprofilerProfiler, self).__init__(output_path)
+ self._browser_backend = browser_backend
+ output_dir = os.path.dirname(self.output_path)
+ output_file = os.path.basename(self.output_path)
+ self._proc = pexpect.spawn(
+ 'iprofiler', ['-timeprofiler', '-T', '300', '-a', str(pid),
+ '-d', output_dir, '-o', output_file],
+ timeout=300)
+ while True:
+ if self._proc.getecho():
+ output = self._proc.readline().strip()
+ if not output:
+ continue
+ if 'iprofiler: Profiling process' in output:
+ break
+ print output
+ self._proc.interact(escape_character='\x0d')
+ self._proc.write('\x0d')
+ print
+ def Echo():
+ return self._proc.getecho()
+ util.WaitFor(Echo, timeout=5)
+
+ @classmethod
+ def name(cls):
+ return 'iprofiler'
+
+ @classmethod
+ def is_supported(cls, options):
+ return (sys.platform == 'darwin'
+ and not options.browser_type.startswith('android')
+ and not options.browser_type.startswith('cros'))
+
+ def CollectProfile(self):
+ self._proc.kill(signal.SIGINT)
+ try:
+ self._proc.wait()
+ except pexpect.ExceptionPexpect:
+ pass
+ finally:
+ self._proc = None
+
+ print 'To view the profile, run:'
+ print ' open -a Instruments %s.dtps' % self.output_path
diff --git a/tools/telemetry/telemetry/core/platform/profiler/profiler_finder.py b/tools/telemetry/telemetry/core/platform/profiler/profiler_finder.py
index cb81cbc..9ae2510 100644
--- a/tools/telemetry/telemetry/core/platform/profiler/profiler_finder.py
+++ b/tools/telemetry/telemetry/core/platform/profiler/profiler_finder.py
@@ -2,10 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from telemetry.core.platform.profiler import iprofiler_profiler
from telemetry.core.platform.profiler import perf_profiler
+from telemetry.core.platform.profiler import sample_profiler
-_PROFILERS = [perf_profiler.PerfProfiler]
+_PROFILERS = [iprofiler_profiler.IprofilerProfiler,
+ perf_profiler.PerfProfiler,
+ sample_profiler.SampleProfiler]
def FindProfiler(name):
diff --git a/tools/telemetry/telemetry/core/platform/profiler/sample_profiler.py b/tools/telemetry/telemetry/core/platform/profiler/sample_profiler.py
new file mode 100644
index 0000000..608b59d
--- /dev/null
+++ b/tools/telemetry/telemetry/core/platform/profiler/sample_profiler.py
@@ -0,0 +1,58 @@
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import signal
+import subprocess
+import sys
+import tempfile
+
+from telemetry.core import util
+from telemetry.core.platform import profiler
+
+
+class SampleProfiler(profiler.Profiler):
+
+ def __init__(self, browser_backend, pid, output_path):
+ super(SampleProfiler, self).__init__(output_path)
+ self._browser_backend = browser_backend
+ self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
+ self._proc = subprocess.Popen(
+ ['sample', str(pid), '-mayDie', '-file', self.output_path],
+ stdout=self._tmp_output_file, stderr=subprocess.STDOUT)
+ def IsStarted():
+ return 'Sampling process' in self._GetStdOut()
+ util.WaitFor(IsStarted, 120)
+
+ @classmethod
+ def name(cls):
+ return 'sample'
+
+ @classmethod
+ def is_supported(cls, options):
+ return (sys.platform == 'darwin'
+ and not options.browser_type.startswith('android')
+ and not options.browser_type.startswith('cros'))
+
+ def CollectProfile(self):
+ self._proc.send_signal(signal.SIGINT)
+ exit_code = self._proc.wait()
+ try:
+ if exit_code:
+ raise Exception(
+ 'sample failed with exit code %d. Output:\n%s' % (
+ exit_code, self._GetStdOut()))
+ finally:
+ self._proc = None
+ self._tmp_output_file.close()
+
+ print 'To view the profile, run:'
+ print ' open -a TextEdit %s' % self.output_path
+
+ def _GetStdOut(self):
+ self._tmp_output_file.flush()
+ try:
+ with open(self._tmp_output_file.name) as f:
+ return f.read()
+ except IOError:
+ return ''