13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import json 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import logging 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import re 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import signal 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import subprocess 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import sys 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import tempfile 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)from telemetry.core.platform import profiler 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)from telemetry.timeline import model 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Parses one line of strace output, for example: 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# 6052 1311456063.159722 read(8, "\1\0\0\0\0\0\0\0", 8) = 8 <0.000022> 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)_STRACE_LINE_RE = re.compile( 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '^(?P<tid>\d+)\s+' 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<ts>\d+)' 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<micro>.\d+)\s+' 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<func>.*?)' 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '[(](?P<args>.*?)[)]\s+=\s+' 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<ret>.*?)\s+' 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '<(?P<dur>[\d.]+)>$') 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)_UNFINISHED_LINE_RE = re.compile( 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '^(?P<tid>\d+)\s+' 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<line>.*?)' 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '<unfinished ...>$') 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)_RESUMED_LINE_RE = re.compile( 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '^(?P<tid>\d+)\s+' 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<ts>\d+)' 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<micro>.\d+)\s+' 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '<[.][.][.]\s(?P<func>.*?)\sresumed>' 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<line>.*?)$') 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)_KILLED_LINE_RE = re.compile( 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '^(?P<tid>\d+)\s+' 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<ts>\d+)' 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '(?P<micro>.\d+)\s+' 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '[+][+][+] killed by SIGKILL [+][+][+]$') 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)def _StraceToChromeTrace(pid, infile): 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) """Returns chrometrace json format for |infile| strace output.""" 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # Map of fd:file_name for open file descriptors. Useful for displaying 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # file name instead of the descriptor number. 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fd_map = {} 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # Map of tid:interrupted_call for the interrupted call on each thread. It is 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # possible to context switch during a system call. In this case we must 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # match up the lines. 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) interrupted_call_map = {} 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out = [] 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) with open(infile, 'r') as f: 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for line in f.readlines(): 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # Ignore kill lines for now. 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) m = _KILLED_LINE_RE.match(line) 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if m: 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # If this line is interrupted, then remember it and continue. 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) m = _UNFINISHED_LINE_RE.match(line) 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if m: 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert m.group('tid') not in interrupted_call_map 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) interrupted_call_map[m.group('tid')] = line 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # If this is a resume of a previous line, stitch it together. 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) interrupted = False 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) m = _RESUMED_LINE_RE.match(line) 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if m: 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) interrupted = True 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert m.group('tid') in interrupted_call_map 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) line = interrupted_call_map[m.group('tid')].replace( 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '<unfinished ...>', m.group('line')) 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) del interrupted_call_map[m.group('tid')] 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # At this point we can do a normal match. 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) m = _STRACE_LINE_RE.match(line) 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if not m: 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if ('exit' not in line and 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'Profiling timer expired' not in line and 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '<unavailable>' not in line): 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) logging.warn('Failed to parse line: %s' % line) 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ts_begin = int(1000000 * (int(m.group('ts')) + float(m.group('micro')))) 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ts_end = ts_begin + int(1000000 * float(m.group('dur'))) 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) tid = int(m.group('tid')) 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) function_name = unicode(m.group('func'), errors='ignore') 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) function_args = unicode(m.group('args'), errors='ignore') 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ret = unicode(m.group('ret'), errors='ignore') 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) cat = 'strace' 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) possible_fd_arg = None 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) first_arg = function_args.split(',')[0] 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if first_arg and first_arg.strip().isdigit(): 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) possible_fd_arg = first_arg.strip() 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if function_name == 'open' and ret.isdigit(): 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # 1918 1311606151.649379 open("/foo/bar.so", O_RDONLY) = 7 <0.000088> 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fd_map[ret] = first_arg 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args = { 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'args': function_args, 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ret': ret, 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if interrupted: 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args['interrupted'] = True 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if possible_fd_arg and possible_fd_arg in fd_map: 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args['fd%s' % first_arg] = fd_map[possible_fd_arg] 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out.append({ 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'cat': cat, 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'pid': pid, 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'tid': tid, 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ts': ts_begin, 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ph': 'B', # Begin 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'name': function_name, 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }) 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out.append({ 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'cat': cat, 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'pid': pid, 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'tid': tid, 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ts': ts_end, 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ph': 'E', # End 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'name': function_name, 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'args': args, 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }) 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return out 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)def _GenerateTraceMetadata(timeline_model): 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out = [] 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for process in timeline_model.processes: 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out.append({ 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'name': 'process_name', 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ph': 'M', # Metadata 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'pid': process, 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'args': { 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'name': timeline_model.processes[process].name 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for thread in timeline_model.processes[process].threads: 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out.append({ 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'name': 'thread_name', 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'ph': 'M', # Metadata 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'pid': process, 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'tid': thread, 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'args': { 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'name': timeline_model.processes[process].threads[thread].name 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }) 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return out 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class _SingleProcessStraceProfiler(object): 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) """An internal class for using perf for a given process.""" 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def __init__(self, pid, output_file, platform_backend): 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._pid = pid 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._platform_backend = platform_backend 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._output_file = output_file 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0) 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._proc = subprocess.Popen( 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ['strace', '-ttt', '-f', '-T', '-p', str(pid), '-o', output_file], 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) stdout=self._tmp_output_file, stderr=subprocess.STDOUT) 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def CollectProfile(self): 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if ('renderer' in self._output_file and 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) not self._platform_backend.GetCommandLine(self._pid)): 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) logging.warning('Renderer was swapped out during profiling. ' 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 'To collect a full profile rerun with ' 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) '"--extra-browser-args=--single-process"') 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._proc.send_signal(signal.SIGINT) 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) exit_code = self._proc.wait() 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) try: 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if exit_code: 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) raise Exception('strace failed with exit code %d. Output:\n%s' % ( 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) exit_code, self._GetStdOut())) 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) finally: 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._tmp_output_file.close() 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return _StraceToChromeTrace(self._pid, self._output_file) 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def _GetStdOut(self): 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._tmp_output_file.flush() 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) try: 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) with open(self._tmp_output_file.name) as f: 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return f.read() 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) except IOError: 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return '' 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class StraceProfiler(profiler.Profiler): 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def __init__(self, browser_backend, platform_backend, output_path, state): 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) super(StraceProfiler, self).__init__( 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser_backend, platform_backend, output_path, state) 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) assert self._browser_backend.supports_tracing 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._browser_backend.StartTracing(None, 10) 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) process_output_file_map = self._GetProcessOutputFileMap() 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._process_profilers = [] 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._output_file = output_path + '.json' 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for pid, output_file in process_output_file_map.iteritems(): 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if 'zygote' in output_file: 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._process_profilers.append( 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) _SingleProcessStraceProfiler(pid, output_file, platform_backend)) 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @classmethod 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def name(cls): 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 'strace' 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @classmethod 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def is_supported(cls, browser_type): 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if sys.platform != 'linux2': 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return False 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) # TODO(tonyg): This should be supported on android and cros. 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (browser_type.startswith('android') or 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_type.startswith('cros')): 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return False 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return True 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) @classmethod 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def CustomizeBrowserOptions(cls, browser_type, options): 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) options.AppendExtraBrowserArgs([ 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) '--no-sandbox', 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) '--allow-sandbox-debugging' 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ]) 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def CollectProfile(self): 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) print 'Processing trace...' 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out_json = [] 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for single_process in self._process_profilers: 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) out_json.extend(single_process.CollectProfile()) 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) timeline_data = self._browser_backend.StopTracing() 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) timeline_model = model.TimelineModel(timeline_data) 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) out_json.extend(_GenerateTraceMetadata(timeline_model)) 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) with open(self._output_file, 'w') as f: 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) f.write(json.dumps(out_json, separators=(',', ':'))) 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) print 'Trace saved as %s' % self._output_file 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) print 'To view, open in chrome://tracing' 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return [self._output_file] 254