1a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# Copyright 2015 The Chromium Authors. All rights reserved.
2a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# Use of this source code is governed by a BSD-style license that can be
3a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# found in the LICENSE file.
4a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
55ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikimport optparse
6b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wangimport platform
7a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport py_utils
85ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikimport re
9a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport sys
10a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport threading
11a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport zlib
12a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
13a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikfrom devil.android import device_utils
14d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craikfrom devil.android.sdk import version_codes
155ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikfrom py_trace_event import trace_time as trace_time_module
16a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikfrom systrace import trace_result
17a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikfrom systrace import tracing_agents
18a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikfrom systrace import util
19a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
20a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# Text that ADB sends, but does not need to be displayed to the user.
21a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikADB_IGNORE_REGEXP = r'^capturing trace\.\.\. done|^capturing trace\.\.\.'
22a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# The number of seconds to wait on output from ADB.
23a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikADB_STDOUT_READ_TIMEOUT = 0.2
24b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang# The number of seconds to wait for large output from ADB.
25b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei WangADB_LARGE_OUTPUT_TIMEOUT = 600
26a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# The adb shell command to initiate a trace.
27a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikATRACE_BASE_ARGS = ['atrace']
28a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# If a custom list of categories is not specified, traces will include
29a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# these categories (if available on the device).
30d0ebf633155e2d637d289933ef7dbc5d86f73881Chris CraikDEFAULT_CATEGORIES = 'sched,freq,gfx,view,dalvik,webview,'\
31d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik                     'input,disk,am,wm,rs,binder_driver'
32a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# The command to list trace categories.
33a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikLIST_CATEGORIES_ARGS = ATRACE_BASE_ARGS + ['--list_categories']
34a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# Minimum number of seconds between displaying status updates.
35a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikMIN_TIME_BETWEEN_STATUS_UPDATES = 0.2
36a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# ADB sends this text to indicate the beginning of the trace data.
37a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikTRACE_START_REGEXP = r'TRACE\:'
38a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik# Plain-text trace data should always start with this string.
39a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikTRACE_TEXT_HEADER = '# tracer'
40eeb03f366d148f92337cfd7577087ade44ab9285John Reck_FIX_MISSING_TGIDS = True
41eeb03f366d148f92337cfd7577087ade44ab9285John Reck_FIX_CIRCULAR_TRACES = True
42a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
43a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
445ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikdef list_categories(config):
45a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """List the possible trace event categories.
46a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
475ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  This function needs the tracing config since it needs to get the serial
48a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  number of the device to send a command to.
49a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
50a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
515ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik      config: Tracing config.
52a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
535ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  devutils = device_utils.DeviceUtils(config.device_serial_number)
54d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  categories = devutils.RunShellCommand(
55d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      LIST_CATEGORIES_ARGS, check_return=True)
56d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik
57d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  device_sdk_version = util.get_device_sdk_version()
58d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  if device_sdk_version < version_codes.MARSHMALLOW:
59d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    # work around platform bug where rs tag would corrupt trace until M(Api23)
60d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    categories = [c for c in categories if not re.match(r'^\s*rs\s*-', c)]
61d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik
62d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  print '\n'.join(categories)
63a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  if not devutils.HasRoot():
64a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    print '\nNOTE: more categories may be available with adb root\n'
65a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
66a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
67d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craikdef get_available_categories(config, device_sdk_version):
68a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Gets the list of atrace categories available for tracing.
69a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
705ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik      config: Tracing config.
71d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      device_sdk_version: Sdk version int of device to be queried.
72a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
735ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  devutils = device_utils.DeviceUtils(config.device_serial_number)
74d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  categories_output = devutils.RunShellCommand(
75d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      LIST_CATEGORIES_ARGS, check_return=True)
76d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  categories = [c.split('-')[0].strip() for c in categories_output]
77d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik
78d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  if device_sdk_version < version_codes.MARSHMALLOW:
79d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    # work around platform bug where rs tag would corrupt trace until M(Api23)
80d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    categories = [c for c in categories if c != 'rs']
81d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  return categories
82a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
83a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
845ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikdef try_create_agent(config):
85a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Create an Atrace agent.
86a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
87a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
885ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik      config: Command line config.
89a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
905ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if config.target != 'android':
915ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    return None
925ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if config.from_file is not None:
935ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    return None
94a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
95eeb03f366d148f92337cfd7577087ade44ab9285John Reck  if not config.atrace_categories:
96eeb03f366d148f92337cfd7577087ade44ab9285John Reck    return None
97eeb03f366d148f92337cfd7577087ade44ab9285John Reck
98a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # Check device SDK version.
99a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  device_sdk_version = util.get_device_sdk_version()
100d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  if device_sdk_version < version_codes.JELLY_BEAN_MR2:
101d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    print ('Device SDK versions < 18 (Jellybean MR2) not supported.\n'
102a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik           'Your device SDK version is %d.' % device_sdk_version)
1035ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    return None
104d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik
105d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  return AtraceAgent(device_sdk_version)
106a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1075ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikdef _construct_extra_atrace_args(config, categories):
108a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Construct extra arguments (-a, -k, categories) for atrace command.
109a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
110a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
1115ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik      config: Tracing config.
112a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
113a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  extra_args = []
114a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1155ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if config.app_name is not None:
1165ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    extra_args.extend(['-a', config.app_name])
117a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1185ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if config.kfuncs is not None:
1195ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    extra_args.extend(['-k', config.kfuncs])
120a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
121a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  extra_args.extend(categories)
122a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  return extra_args
123a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1245ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikdef _construct_atrace_args(config, categories):
125a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Builds the command used to invoke a trace process.
126a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Returns:
127a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    A tuple where the first element is an array of command arguments, and
128a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    the second element is a boolean which will be true if the command will
129a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    stream trace data.
130a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
131a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  atrace_args = ATRACE_BASE_ARGS[:]
132a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1335ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if config.compress_trace_data:
134a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    atrace_args.extend(['-z'])
135a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1365ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if (config.trace_time is not None) and (config.trace_time > 0):
1375ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    atrace_args.extend(['-t', str(config.trace_time)])
138a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1395ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  if (config.trace_buf_size is not None) and (config.trace_buf_size > 0):
1405ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    atrace_args.extend(['-b', str(config.trace_buf_size)])
141a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
142a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  elif 'sched' in categories:
143a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    # 'sched' is a high-volume tag, double the default buffer size
144a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    # to accommodate that
145a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    atrace_args.extend(['-b', '4096'])
1465ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  extra_args = _construct_extra_atrace_args(config, categories)
147a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
148a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  atrace_args.extend(extra_args)
149a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  return atrace_args
150a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
1515ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik
152a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikclass AtraceAgent(tracing_agents.TracingAgent):
153a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
154d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  def __init__(self, device_sdk_version):
155a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    super(AtraceAgent, self).__init__()
156d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    self._device_sdk_version = device_sdk_version
157a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._adb = None
158a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._trace_data = None
159a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._tracer_args = None
160a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._collection_thread = None
161a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._device_utils = None
162a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._device_serial_number = None
1635ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self._config = None
164a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._categories = None
165a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
166eeb03f366d148f92337cfd7577087ade44ab9285John Reck  def __repr__(self):
167eeb03f366d148f92337cfd7577087ade44ab9285John Reck    return 'atrace'
168eeb03f366d148f92337cfd7577087ade44ab9285John Reck
169a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
1705ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  def StartAgentTracing(self, config, timeout=None):
171eeb03f366d148f92337cfd7577087ade44ab9285John Reck    assert config.atrace_categories, 'Atrace categories are missing!'
1725ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self._config = config
1735ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self._categories = config.atrace_categories
174eeb03f366d148f92337cfd7577087ade44ab9285John Reck    if isinstance(self._categories, list):
175eeb03f366d148f92337cfd7577087ade44ab9285John Reck      self._categories = ','.join(self._categories)
176d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    avail_cats = get_available_categories(config, self._device_sdk_version)
177eeb03f366d148f92337cfd7577087ade44ab9285John Reck    unavailable = [x for x in self._categories.split(',') if
178eeb03f366d148f92337cfd7577087ade44ab9285John Reck        x not in avail_cats]
179eeb03f366d148f92337cfd7577087ade44ab9285John Reck    self._categories = [x for x in self._categories.split(',') if
180eeb03f366d148f92337cfd7577087ade44ab9285John Reck        x in avail_cats]
181a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if unavailable:
182a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      print 'These categories are unavailable: ' + ' '.join(unavailable)
1835ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self._device_utils = device_utils.DeviceUtils(config.device_serial_number)
1845ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self._device_serial_number = config.device_serial_number
1855ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self._tracer_args = _construct_atrace_args(config,
1865ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                                               self._categories)
187d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    self._device_utils.RunShellCommand(
188d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik        self._tracer_args + ['--async_start'], check_return=True)
189a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return True
190a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
191a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def _collect_and_preprocess(self):
192a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Collects and preprocesses trace data.
193a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
194a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    Stores results in self._trace_data.
195a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """
196a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data = self._collect_trace_data()
197a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._trace_data = self._preprocess_trace_data(trace_data)
198a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
199a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
200a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def StopAgentTracing(self, timeout=None):
201a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Stops tracing and starts collecting results.
202a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
203a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    To synchronously retrieve the results after calling this function,
204a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    call GetResults().
205a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """
206a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._collection_thread = threading.Thread(
207a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik        target=self._collect_and_preprocess)
208a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._collection_thread.start()
209a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return True
210a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
211a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  @py_utils.Timeout(tracing_agents.GET_RESULTS_TIMEOUT)
212a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def GetResults(self, timeout=None):
213a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Waits for collection thread to finish and returns trace results."""
214a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._collection_thread.join()
215a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    self._collection_thread = None
216a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return trace_result.TraceResult('systemTraceEvents', self._trace_data)
217a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
218a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def SupportsExplicitClockSync(self):
219a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return True
220a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
221a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def RecordClockSyncMarker(self, sync_id, did_record_sync_marker_callback):
222a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Records a clock sync marker.
223a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
224a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    Args:
225a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik        sync_id: ID string for clock sync marker.
226a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """
227a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    cmd = 'echo trace_event_clock_sync: name=%s >' \
228a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik        ' /sys/kernel/debug/tracing/trace_marker' % sync_id
229a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    with self._device_utils.adb.PersistentShell(
230a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik        self._device_serial_number) as shell:
2315ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik      t1 = trace_time_module.Now()
232a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      shell.RunCommand(cmd, close=True)
233a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      did_record_sync_marker_callback(t1, sync_id)
234a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
235b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang  def _stop_collect_trace(self):
236a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Stops atrace.
237a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
238d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    Note that prior to Api 23, --async-stop may not actually stop tracing.
239d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    Thus, this uses a fallback method of running a zero-length synchronous
240d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    trace if tracing is still on."""
241b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    result = self._device_utils.RunShellCommand(
242b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        self._tracer_args + ['--async_stop'], raw_output=True,
243b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        large_output=True, check_return=True, timeout=ADB_LARGE_OUTPUT_TIMEOUT)
244d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    is_trace_enabled_file = '/sys/kernel/debug/tracing/tracing_on'
245d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik
246d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    if self._device_sdk_version < version_codes.MARSHMALLOW:
247d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      if int(self._device_utils.ReadFile(is_trace_enabled_file)):
248d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik        # tracing was incorrectly left on, disable it
249d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik        self._device_utils.RunShellCommand(
250d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik            self._tracer_args + ['-t 0'], check_return=True)
251a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
252b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    return result
253b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang
254a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def _collect_trace_data(self):
255a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Reads the output from atrace and stops the trace."""
256b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    result = self._stop_collect_trace()
257d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik
258a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    data_start = re.search(TRACE_START_REGEXP, result)
259a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if data_start:
260a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      data_start = data_start.end(0)
261a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    else:
262a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      raise IOError('Unable to get atrace data. Did you forget adb root?')
263a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    output = re.sub(ADB_IGNORE_REGEXP, '', result[data_start:])
264a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return output
265a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
266a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def _preprocess_trace_data(self, trace_data):
267a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """Performs various processing on atrace data.
268a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
269a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    Args:
270a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      trace_data: The raw trace data.
271a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    Returns:
272a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      The processed trace data.
273a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    """
274a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if trace_data:
275a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      trace_data = strip_and_decompress_trace(trace_data)
276a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
277a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if not trace_data:
278a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      print >> sys.stderr, ('No data was captured.  Output file was not '
279a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik                            'written.')
280a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      sys.exit(1)
281a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
282eeb03f366d148f92337cfd7577087ade44ab9285John Reck    if _FIX_MISSING_TGIDS:
283576fd2a645575980f16b6731dab0f4f150100657Chris Craik      # Gather proc data from device and patch tgids
284d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      procfs_dump = self._device_utils.RunShellCommand(
285576fd2a645575980f16b6731dab0f4f150100657Chris Craik          'echo -n /proc/[0-9]*/task/[0-9]*',
286576fd2a645575980f16b6731dab0f4f150100657Chris Craik          shell=True, check_return=True)[0].split(' ')
287d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      pid2_tgid = extract_tgids(procfs_dump)
288d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik      trace_data = fix_missing_tgids(trace_data, pid2_tgid)
289a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
290eeb03f366d148f92337cfd7577087ade44ab9285John Reck    if _FIX_CIRCULAR_TRACES:
291a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      trace_data = fix_circular_traces(trace_data)
292a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
293a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return trace_data
294a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
295d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craikdef extract_tgids(trace_lines):
296a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Removes the procfs dump from the given trace text
297a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
298a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
299d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik    trace_lines: The text portion of the trace
300a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
301a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Returns:
302a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    a map of pids to their tgid.
303a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
304a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  tgid_2pid = {}
305d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik  for line in trace_lines:
306a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    result = re.match('^/proc/([0-9]+)/task/([0-9]+)', line)
307a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if result:
308a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      parent_pid, tgid = result.group(1, 2)
309a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      tgid_2pid[tgid] = parent_pid
310a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
311a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  return tgid_2pid
312a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
313a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
314a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef strip_and_decompress_trace(trace_data):
315a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Fixes new-lines and decompresses trace data.
316a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
317a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
318a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data: The trace data returned by atrace.
319a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Returns:
320a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    The decompressed trace data.
321a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
322a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # Collapse CRLFs that are added by adb shell.
323a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  if trace_data.startswith('\r\n'):
324a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data = trace_data.replace('\r\n', '\n')
325a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  elif trace_data.startswith('\r\r\n'):
326a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    # On windows, adb adds an extra '\r' character for each line.
327a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data = trace_data.replace('\r\r\n', '\n')
328a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
329a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # Skip the initial newline.
330a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  if trace_data[0] == '\n':
331a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data = trace_data[1:]
332a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
333a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  if not trace_data.startswith(TRACE_TEXT_HEADER):
334a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    # No header found, so assume the data is compressed.
335a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data = zlib.decompress(trace_data)
336a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
337a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # Enforce Unix line-endings.
338a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  trace_data = trace_data.replace('\r', '')
339a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
340a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # Skip any initial newlines.
341a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  while trace_data and trace_data[0] == '\n':
342a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data = trace_data[1:]
343a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
344a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  return trace_data
345a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
346a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
347a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef fix_missing_tgids(trace_data, pid2_tgid):
348a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Replaces missing TGIDs from the trace data with those found in procfs
349a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
350a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
351a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    trace_data: the atrace data
352a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
353a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Returns:
354a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    The updated trace data with missing TGIDs replaced with the correct TGID
355a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
356a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
357a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  def repl(m):
358a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    tid = m.group(2)
359a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if (int(tid) > 0 and m.group(1) != '<idle>' and m.group(3) == '(-----)'
360a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik        and tid in pid2_tgid):
361a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      # returns Proc_name-PID (TGID)
362a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      # Binder_2-381 (-----) becomes Binder_2-381 (128)
363a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      return m.group(1) + '-' + m.group(2) + ' ( ' + pid2_tgid[tid] + ')'
364a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
365a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return m.group(0)
366a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
367a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # matches something like:
368a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # Binder_2-895 (-----)
369a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  trace_data = re.sub(r'^\s*(\S+)-(\d+)\s+(\(\S+\))', repl, trace_data,
370a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik                      flags=re.MULTILINE)
371a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  return trace_data
372a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
373a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
374a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef fix_circular_traces(out):
375a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """Fix inconsistentcies in traces due to circular buffering.
376a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
377a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  The circular buffers are kept per CPU, so it is not guaranteed that the
378a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  beginning of a slice is overwritten before the end. To work around this, we
379a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  throw away the prefix of the trace where not all CPUs have events yet.
380a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
381a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Args:
382a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    out: The data to fix.
383a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  Returns:
384a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    The updated trace data.
385a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  """
386a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # If any of the CPU's buffers have filled up and
387a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # older events have been dropped, the kernel
388a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # emits markers of the form '##### CPU 2 buffer started ####' on
389a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # the line before the first event in the trace on that CPU.
390a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  #
391a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # No such headers are emitted if there were no overflows or the trace
392a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # was captured with non-circular buffers.
393a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  buffer_start_re = re.compile(r'^#+ CPU \d+ buffer started', re.MULTILINE)
394a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
395a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  start_of_full_trace = 0
396a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
397a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  while True:
398a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    result = buffer_start_re.search(out, start_of_full_trace + 1)
399a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if result:
400a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      start_of_full_trace = result.start()
401a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    else:
402a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      break
403a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
404a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  if start_of_full_trace > 0:
405a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    # Need to keep the header intact to make the importer happy.
406a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    end_of_header = re.search(r'^[^#]', out, re.MULTILINE).start()
407a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    out = out[:end_of_header] + out[start_of_full_trace:]
408a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  return out
409a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
4105ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik
4115ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikclass AtraceConfig(tracing_agents.TracingConfig):
4125ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  def __init__(self, atrace_categories, trace_buf_size, kfuncs,
413d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik               app_name, compress_trace_data, from_file,
414eeb03f366d148f92337cfd7577087ade44ab9285John Reck               device_serial_number, trace_time, target):
4155ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    tracing_agents.TracingConfig.__init__(self)
4165ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.atrace_categories = atrace_categories
4175ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.trace_buf_size = trace_buf_size
4185ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.kfuncs = kfuncs
4195ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.app_name = app_name
420b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # Trace compression is broken on Windows.
421b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    # TODO: Fix https://crbug.com/739751.
422b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang    self.compress_trace_data = \
423b2cf025c7d5cebd43084f38c6c7ff9cc17da428aWei Wang        compress_trace_data and platform.system() != 'Windows'
4245ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.from_file = from_file
4255ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.device_serial_number = device_serial_number
4265ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.trace_time = trace_time
4275ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik    self.target = target
4285ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik
4295ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik
4305ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikdef add_options(parser):
4315ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  options = optparse.OptionGroup(parser, 'Atrace options')
4325ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  options.add_option('--atrace-categories', dest='atrace_categories',
4335ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     help='Select atrace categories with a comma-delimited '
4345ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     'list, e.g. --atrace-categories=cat1,cat2,cat3')
4355ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  options.add_option('-k', '--ktrace', dest='kfuncs', action='store',
4365ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     help='specify a comma-separated list of kernel functions '
4375ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     'to trace')
4385ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  options.add_option('--no-compress', dest='compress_trace_data',
4395ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     default=True, action='store_false',
4405ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     help='Tell the device not to send the trace data in '
4415ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                     'compressed form.')
442eeb03f366d148f92337cfd7577087ade44ab9285John Reck  options.add_option('-a', '--app', dest='app_name', default=None,
443eeb03f366d148f92337cfd7577087ade44ab9285John Reck                     type='string', action='store',
444eeb03f366d148f92337cfd7577087ade44ab9285John Reck                     help='enable application-level tracing for '
445eeb03f366d148f92337cfd7577087ade44ab9285John Reck                     'comma-separated list of app cmdlines')
446eeb03f366d148f92337cfd7577087ade44ab9285John Reck  options.add_option('--from-file', dest='from_file',
447eeb03f366d148f92337cfd7577087ade44ab9285John Reck                     action='store', help='read the trace from a '
448eeb03f366d148f92337cfd7577087ade44ab9285John Reck                     'file (compressed) rather than running a '
449eeb03f366d148f92337cfd7577087ade44ab9285John Reck                     'live trace')
4505ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  return options
4515ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik
4525ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craikdef get_config(options):
4535ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik  return AtraceConfig(options.atrace_categories,
4545ad62731e62b9eb8d13f6e66dd1b57deaebdee11Chris Craik                      options.trace_buf_size, options.kfuncs,
455eeb03f366d148f92337cfd7577087ade44ab9285John Reck                      options.app_name, options.compress_trace_data,
456d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik                      options.from_file, options.device_serial_number,
457d0ebf633155e2d637d289933ef7dbc5d86f73881Chris Craik                      options.trace_time, options.target)
458