diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-26 11:12:04 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-26 11:12:04 +0000 |
commit | 37572cc8fa71fc89e89a2502959c78a319a732cd (patch) | |
tree | a9a74ea6328d53c2449d0574ecb617a22db16bbe /tools | |
parent | 68f6dcb79442a89bfe07988427d3ac491e1c9477 (diff) | |
download | chromium_src-37572cc8fa71fc89e89a2502959c78a319a732cd.zip chromium_src-37572cc8fa71fc89e89a2502959c78a319a732cd.tar.gz chromium_src-37572cc8fa71fc89e89a2502959c78a319a732cd.tar.bz2 |
Telemetry: adds TCPDump profiler for linux and android.
This profiler will help tracking down issues such as crbug.com/253307
BUG=253307,263397
Review URL: https://chromiumcodereview.appspot.com/19857007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213837 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
-rw-r--r-- | tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py | 8 | ||||
-rw-r--r-- | tools/telemetry/telemetry/core/platform/profiler/tcpdump_profiler.py | 105 |
2 files changed, 108 insertions, 5 deletions
diff --git a/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py b/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py index a82eb98..30f6e2c 100644 --- a/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py +++ b/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py @@ -98,7 +98,7 @@ class TCMallocHeapProfiler(profiler.Profiler): def __init__(self, browser_backend, platform_backend, output_path): super(TCMallocHeapProfiler, self).__init__( browser_backend, platform_backend, output_path) - if self._browser_backend.options.browser_type.startswith('android'): + if platform_backend.GetOSName() == 'android': self._platform_profiler = _TCMallocHeapProfilerAndroid( browser_backend, output_path) else: @@ -110,10 +110,8 @@ class TCMallocHeapProfiler(profiler.Profiler): @classmethod def is_supported(cls, options): - if (not sys.platform.startswith('linux') or - options.browser_type.startswith('cros')): - return False - return True + return (sys.platform.startswith('linux') and + not options.browser_type.startswith('cros')) def CollectProfile(self): self._platform_profiler.CollectProfile() diff --git a/tools/telemetry/telemetry/core/platform/profiler/tcpdump_profiler.py b/tools/telemetry/telemetry/core/platform/profiler/tcpdump_profiler.py new file mode 100644 index 0000000..c73c44f --- /dev/null +++ b/tools/telemetry/telemetry/core/platform/profiler/tcpdump_profiler.py @@ -0,0 +1,105 @@ +# Copyright 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 subprocess +import sys +import tempfile + +from telemetry.core.platform import profiler + + +_TCP_DUMP_BASE_OPTS = ['-i', 'any', '-p', '-s', '0', '-w'] + +class _TCPDumpProfilerAndroid(object): + """An internal class to collect TCP dumps on android.""" + + _TCP_DUMP = '/data/local/tmp/tcpdump' + _DEVICE_DUMP_FILE = '/sdcard/capture.pcap' + + def __init__(self, adb, output_path): + self._adb = adb + self._output_path = output_path + self._proc = subprocess.Popen( + ['adb', '-s', self._adb.device(), + 'shell', self._TCP_DUMP] + _TCP_DUMP_BASE_OPTS + + [self._DEVICE_DUMP_FILE]) + + def CollectProfile(self): + tcpdump_pid = self._adb.ExtractPid('tcpdump') + if not tcpdump_pid or not tcpdump_pid[0]: + raise Exception('Unable to find TCPDump. Check your device is rooted ' + 'and tcpdump is installed at ' + self._TCP_DUMP) + self._adb.RunShellCommand('kill -term ' + tcpdump_pid[0]) + self._proc.terminate() + host_dump = os.path.join(self._output_path, + os.path.basename(self._DEVICE_DUMP_FILE)) + self._adb.Adb().Adb().Pull(self._DEVICE_DUMP_FILE, host_dump) + print 'TCP dump available at: %s ' % host_dump + print 'Use Wireshark to open it.' + + +class _TCPDumpProfilerLinux(object): + """An internal class to collect TCP dumps on linux desktop.""" + + _DUMP_FILE = 'capture.pcap' + + def __init__(self, output_path): + if not os.path.exists(output_path): + os.makedirs(output_path) + self._dump_file = os.path.join(output_path, self._DUMP_FILE) + self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0) + try: + self._proc = subprocess.Popen( + ['tcpdump'] + _TCP_DUMP_BASE_OPTS + [self._dump_file], + stdout=self._tmp_output_file, stderr=subprocess.STDOUT) + except OSError as e: + raise Exception('Unable to execute TCPDump, please check your ' + 'installation. ' + str(e)) + + def CollectProfile(self): + self._proc.send_signal(signal.SIGINT) + exit_code = self._proc.wait() + try: + if exit_code: + raise Exception( + 'tcpdump failed with exit code %d. Output:\n%s' % + (exit_code, self._GetStdOut())) + finally: + self._tmp_output_file.close() + print 'TCP dump available at: ', self._dump_file + print 'Use Wireshark to open it.' + + def _GetStdOut(self): + self._tmp_output_file.flush() + try: + with open(self._tmp_output_file.name) as f: + return f.read() + except IOError: + return '' + + +class TCPDumpProfiler(profiler.Profiler): + """A Factory to instantiate the platform-specific profiler.""" + def __init__(self, browser_backend, platform_backend, output_path): + super(TCPDumpProfiler, self).__init__( + browser_backend, platform_backend, output_path) + if platform_backend.GetOSName() == 'android': + self._platform_profiler = _TCPDumpProfilerAndroid( + browser_backend.adb, output_path) + else: + self._platform_profiler = _TCPDumpProfilerLinux(output_path) + + @classmethod + def name(cls): + return 'tcpdump' + + @classmethod + def is_supported(cls, options): + return (sys.platform.startswith('linux') and + not options.browser_type.startswith('cros')) + + def CollectProfile(self): + self._platform_profiler.CollectProfile() |