1 # Copyright 2016 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. 4 5 import os 6 import py_utils 7 import re 8 9 from systrace import trace_result 10 from systrace import tracing_agents 11 from systrace.tracing_agents import atrace_agent 12 13 14 # ADB sends this text to indicate the beginning of the trace data. 15 TRACE_START_REGEXP = r'TRACE\:' 16 # Text that ADB sends, but does not need to be displayed to the user. 17 ADB_IGNORE_REGEXP = r'^capturing trace\.\.\. done|^capturing trace\.\.\.' 18 19 20 def try_create_agent(options): 21 if options.from_file is not None: 22 return AtraceFromFileAgent(options) 23 else: 24 return False 25 26 27 class AtraceFromFileConfig(tracing_agents.TracingConfig): 28 def __init__(self, from_file): 29 tracing_agents.TracingConfig.__init__(self) 30 self.fix_circular = True 31 self.from_file = from_file 32 33 def add_options(parser): # pylint: disable=unused-argument 34 # The atrace_from_file_agent is not currently used, so don't display 35 # any options. 36 return None 37 38 def get_config(options): 39 return AtraceFromFileConfig(options.from_file) 40 41 42 class AtraceFromFileAgent(tracing_agents.TracingAgent): 43 def __init__(self, options): 44 super(AtraceFromFileAgent, self).__init__() 45 self._filename = os.path.expanduser(options.from_file) 46 self._trace_data = False 47 48 @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT) 49 def StartAgentTracing(self, config, timeout=None): 50 # pylint: disable=unused-argument 51 return True 52 53 @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT) 54 def StopAgentTracing(self, timeout=None): 55 self._trace_data = self._read_trace_data() 56 return True 57 58 def SupportsExplicitClockSync(self): 59 return False 60 61 def RecordClockSyncMarker(self, sync_id, did_record_clock_sync_callback): 62 raise NotImplementedError 63 64 @py_utils.Timeout(tracing_agents.GET_RESULTS_TIMEOUT) 65 def GetResults(self, timeout=None): 66 return trace_result.TraceResult('trace-data', self._trace_data) 67 68 def _read_trace_data(self): 69 with open(self._filename, 'rb') as f: 70 result = f.read() 71 data_start = re.search(TRACE_START_REGEXP, result).end(0) 72 data = re.sub(ADB_IGNORE_REGEXP, '', result[data_start:]) 73 return self._preprocess_data(data) 74 75 # pylint: disable=no-self-use 76 def _preprocess_data(self, data): 77 # TODO: add fix_threads and fix_tgids options back in here 78 # once we embed the dump data in the file (b/27504068) 79 data = atrace_agent.strip_and_decompress_trace(data) 80 data = atrace_agent.fix_circular_traces(data) 81 return data 82