blob: f25ecaebceb3fbfe6155fda70ec6545c7603af89 [file] [log] [blame]
# Copyright 2021 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.
"""This script provides the necessary flags to symbolize proto traces.
"""
import logging
import optparse
import os
import sys
sys.path.insert(
0,
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'third_party',
'catapult', 'systrace'))
from systrace import util
TRACING_LOGGER_NAME = 'chromium:tools/tracing'
def GeneralOptions(parser):
"""Build option group for general options.
Args:
parser: OptionParser object for parsing the command-line.
Returns:
Option group that contains general options.
"""
general_options = optparse.OptionGroup(parser, 'General Options')
general_options.add_option('-o',
'--output',
help=('Save trace output to file. '
'Defaults to trace_file + '
'"_symbolized_trace."'),
dest='output_file')
general_options.add_option('-v',
'--verbose',
help='Increase output verbosity.',
action='count',
dest='verbosity',
default=0)
general_options.add_option('--view',
help='Open resulting trace file in a '
'browser.',
action='store_true',
dest='view')
return general_options
def ProfileOptions(parser):
"""Build option group for profiling chrome.
Args:
parser: OptionParser object for parsing the command-line.
Returns:
Option group that contains profiling chrome options.
"""
profile_options = optparse.OptionGroup(parser, 'Profile Chrome Options')
browsers = sorted(util.get_supported_browsers().keys())
profile_options.add_option('-b',
'--browser',
help='Select among installed browsers. '
'One of ' + ', '.join(browsers) +
'. "stable" is used by '
'default.',
type='choice',
choices=browsers,
default='stable')
profile_options.add_option('-t',
'--time',
help=('Stops tracing after N seconds. '
'Default is 5 seconds'),
default=5,
metavar='N',
type='int',
dest='trace_time')
profile_options.add_option('-e',
'--serial',
help='adb device serial number.',
type='string',
default=util.get_default_serial(),
dest='device_serial_number')
profile_options.add_option('-f',
'--trace_format',
help='Format of saved trace: proto, json, html.'
' Default is proto.',
default='proto',
dest='trace_format')
profile_options.add_option('-p',
'--platform',
help='Device platform. Only Android is supported.',
default='android',
dest='platform')
profile_options.add_option('--buf-size',
help='Use a trace buffer size '
' of N KB.',
type='int',
metavar='N',
dest='trace_buf_size')
profile_options.add_option(
'--enable_profiler',
help='Comma-separated string of '
'profiling options to use. Supports options for memory or '
'cpu or both. Ex: --enable_profiler=memory '
'or --enable_profiler=memory,cpu. ',
dest='enable_profiler')
profile_options.add_option('--chrome_categories',
help='Chrome tracing '
'categories to record.',
type='string')
profile_options.add_option(
'--skip_symbolize',
help='Skips symbolization after recording trace profile, if specified.',
action='store_true',
dest='skip_symbolize')
profile_options.add_option('--compress',
help='Compress the resulting trace '
'with gzip. ',
action='store_true')
# This is kept for backwards compatibility. Help is suppressed because this
# should be specified through the newer |trace_format| flag.
profile_options.add_option('--json',
help=optparse.SUPPRESS_HELP,
dest='write_json')
return profile_options
def SymbolizeOptions(parser):
"""Build option group for proto trace symbolization.
Args:
parser: OptionParser object for parsing the command-line.
Returns:
Option group that contains symbolization options.
"""
symbolization_options = optparse.OptionGroup(parser, 'Symbolization Options')
symbolization_options.add_option(
'--breakpad_output_dir',
help='Optional path to empty directory to store fetched trace symbols '
'and extracted breakpad symbol files for official builds. Useful '
'for symbolizing multiple traces from the same Chrome build. Use '
'--local_breakpad_dir when you already have breakpad files fetched. '
'Automatically uses temporary directory if flag not specified.',
dest='breakpad_output_dir')
symbolization_options.add_option(
'--local_breakpad_dir',
help='Optional path to local directory containing breakpad symbol files '
'used to symbolize the given trace. Breakpad files should be named '
'with module id in upper case hexadecimal and ".breakpad" '
'suffix. Ex: 12EFA32BE.breakpad',
dest='local_breakpad_dir')
symbolization_options.add_option(
'--local_build_dir',
help='Optional path to a local build directory containing symbol files.',
dest='local_build_dir')
symbolization_options.add_option(
'--dump_syms',
help=('Path to a dump_syms binary. Required when symbolizing an official '
'build. Optional on local builds as we can use --local_build_dir '
'to locate a binary. If built locally with '
'autoninja -C out/Release dump_syms then the binary path is '
'out/Release/dump_syms'),
dest='dump_syms_path')
symbolization_options.add_option(
'--symbolizer',
help=('Path to the trace_to_text binary for symbolization. Defaults to '
'"third_party/perfetto/tools/traceconv". traceconv is the same as '
'trace_to_text, except that tracevonv finds a prebuilt '
'trace_to_text binary to use.'),
default='third_party/perfetto/tools/traceconv',
dest='symbolizer_path')
symbolization_options.add_option(
'--trace_processor',
help=('Optional path to trace processor binary. '
'Automatically downloads binary if flag not specified.'),
dest='trace_processor_path')
symbolization_options.add_option(
'--cloud_storage_bucket',
help=('Optional cloud storage bucket to where symbol files reside. '
'Defaults to "chrome-unsigned".'),
default='chrome-unsigned',
dest='cloud_storage_bucket')
return symbolization_options
def SetupProfilingCategories(options):
"""Sets --chrome_categories flag.
Uses the --enable_profile flag to modify the --chrome_categories flag for
specific profiling options.
Args:
options: The command-line options given.
"""
if options.enable_profiler is None:
if not options.chrome_categories:
GetTracingLogger().warning(
'No trace category or profiler is enabled using --enable_profiler '
'and/or --chrome_categories, enabling all default categories.')
if not options.skip_symbolize:
GetTracingLogger().warning(
'No profiler is enabled, symbolization might fail without any '
'frames. Use --skip_symbolize to disable symbolization.')
else:
GetTracingLogger().info(
'No profiler is enabled, the trace will only have trace events.')
return
if options.chrome_categories is None:
options.chrome_categories = ''
profile_options = options.enable_profiler.split(',')
# Add to the --chrome_categories flag.
if 'cpu' in profile_options:
if options.chrome_categories:
options.chrome_categories += ','
options.chrome_categories += 'disabled-by-default-cpu_profiler'
if 'memory' in profile_options:
if options.chrome_categories:
options.chrome_categories += ',disabled-by-default-memory-infra'
else:
# If heap profiling is enabled and no categories are provided, it is
# usually not helpful to include other information in traces. '-*'
# disables other default categories so that only memory data is recorded.
options.chrome_categories += 'disabled-by-default-memory-infra,-*'
def GetTracingLogger():
"""Returns the logger for tools/tracing."""
return logging.getLogger(TRACING_LOGGER_NAME)
def SetupLogging(verbosity):
"""Setup logging levels.
Sets default level to warning.
Args:
verbosity: None or integer type that specifies the logging level.
(options.verbosity)
"""
logger = GetTracingLogger()
if verbosity == 1:
logging.basicConfig(level=logging.INFO)
logger.setLevel(level=logging.INFO)
elif verbosity >= 2:
logging.basicConfig(level=logging.DEBUG)
logger.setLevel(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.WARNING)
logger.setLevel(level=logging.WARNING)