| # Copyright 2021 The Chromium Authors |
| # 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) |