Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame] | 1 | # Copyright 2021 The Chromium Authors |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 4 | """This script provides the necessary flags to symbolize proto traces. |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 5 | """ |
| 6 | |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 7 | import logging |
| 8 | import optparse |
Uwem Wilson | d4f50c7 | 2021-08-02 22:03:50 | [diff] [blame] | 9 | import os |
| 10 | import sys |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 11 | |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 12 | |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 13 | sys.path.insert( |
| 14 | 0, |
| 15 | os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'third_party', |
| 16 | 'catapult', 'systrace')) |
| 17 | from systrace import util |
| 18 | |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 19 | TRACING_LOGGER_NAME = 'chromium:tools/tracing' |
| 20 | |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 21 | |
| 22 | def GeneralOptions(parser): |
| 23 | """Build option group for general options. |
| 24 | |
| 25 | Args: |
| 26 | parser: OptionParser object for parsing the command-line. |
| 27 | |
| 28 | Returns: |
| 29 | Option group that contains general options. |
| 30 | """ |
| 31 | general_options = optparse.OptionGroup(parser, 'General Options') |
| 32 | |
| 33 | general_options.add_option('-o', |
| 34 | '--output', |
| 35 | help=('Save trace output to file. ' |
| 36 | 'Defaults to trace_file + ' |
| 37 | '"_symbolized_trace."'), |
| 38 | dest='output_file') |
| 39 | general_options.add_option('-v', |
| 40 | '--verbose', |
| 41 | help='Increase output verbosity.', |
| 42 | action='count', |
ssid | e4392fc | 2021-11-23 22:07:13 | [diff] [blame] | 43 | dest='verbosity', |
| 44 | default=0) |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 45 | general_options.add_option('--view', |
| 46 | help='Open resulting trace file in a ' |
| 47 | 'browser.', |
Ryan Huckleberry | ddfa54c | 2021-08-06 18:48:04 | [diff] [blame] | 48 | action='store_true', |
| 49 | dest='view') |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 50 | |
| 51 | return general_options |
| 52 | |
| 53 | |
| 54 | def ProfileOptions(parser): |
| 55 | """Build option group for profiling chrome. |
| 56 | |
| 57 | Args: |
| 58 | parser: OptionParser object for parsing the command-line. |
| 59 | |
| 60 | Returns: |
| 61 | Option group that contains profiling chrome options. |
| 62 | """ |
| 63 | profile_options = optparse.OptionGroup(parser, 'Profile Chrome Options') |
| 64 | browsers = sorted(util.get_supported_browsers().keys()) |
| 65 | |
| 66 | profile_options.add_option('-b', |
| 67 | '--browser', |
| 68 | help='Select among installed browsers. ' |
| 69 | 'One of ' + ', '.join(browsers) + |
| 70 | '. "stable" is used by ' |
| 71 | 'default.', |
| 72 | type='choice', |
| 73 | choices=browsers, |
| 74 | default='stable') |
| 75 | profile_options.add_option('-t', |
| 76 | '--time', |
| 77 | help=('Stops tracing after N seconds. ' |
| 78 | 'Default is 5 seconds'), |
| 79 | default=5, |
| 80 | metavar='N', |
| 81 | type='int', |
| 82 | dest='trace_time') |
| 83 | profile_options.add_option('-e', |
| 84 | '--serial', |
| 85 | help='adb device serial number.', |
| 86 | type='string', |
| 87 | default=util.get_default_serial(), |
| 88 | dest='device_serial_number') |
| 89 | profile_options.add_option('-f', |
| 90 | '--trace_format', |
| 91 | help='Format of saved trace: proto, json, html.' |
| 92 | ' Default is proto.', |
| 93 | default='proto', |
| 94 | dest='trace_format') |
| 95 | profile_options.add_option('-p', |
| 96 | '--platform', |
| 97 | help='Device platform. Only Android is supported.', |
| 98 | default='android', |
| 99 | dest='platform') |
| 100 | profile_options.add_option('--buf-size', |
| 101 | help='Use a trace buffer size ' |
| 102 | ' of N KB.', |
| 103 | type='int', |
| 104 | metavar='N', |
| 105 | dest='trace_buf_size') |
| 106 | profile_options.add_option( |
| 107 | '--enable_profiler', |
| 108 | help='Comma-separated string of ' |
| 109 | 'profiling options to use. Supports options for memory or ' |
| 110 | 'cpu or both. Ex: --enable_profiler=memory ' |
| 111 | 'or --enable_profiler=memory,cpu. ', |
| 112 | dest='enable_profiler') |
| 113 | profile_options.add_option('--chrome_categories', |
| 114 | help='Chrome tracing ' |
| 115 | 'categories to record.', |
ssid | 2266735 | 2021-11-29 21:06:53 | [diff] [blame] | 116 | type='string') |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 117 | profile_options.add_option( |
Ryan Huckleberry | 855b1af | 2021-08-12 01:10:36 | [diff] [blame] | 118 | '--skip_symbolize', |
| 119 | help='Skips symbolization after recording trace profile, if specified.', |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 120 | action='store_true', |
Ryan Huckleberry | 855b1af | 2021-08-12 01:10:36 | [diff] [blame] | 121 | dest='skip_symbolize') |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 122 | profile_options.add_option('--compress', |
| 123 | help='Compress the resulting trace ' |
| 124 | 'with gzip. ', |
| 125 | action='store_true') |
| 126 | |
| 127 | # This is kept for backwards compatibility. Help is suppressed because this |
| 128 | # should be specified through the newer |trace_format| flag. |
| 129 | profile_options.add_option('--json', |
| 130 | help=optparse.SUPPRESS_HELP, |
| 131 | dest='write_json') |
| 132 | |
| 133 | return profile_options |
| 134 | |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 135 | |
| 136 | def SymbolizeOptions(parser): |
| 137 | """Build option group for proto trace symbolization. |
| 138 | |
| 139 | Args: |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 140 | parser: OptionParser object for parsing the command-line. |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 141 | |
| 142 | Returns: |
| 143 | Option group that contains symbolization options. |
| 144 | """ |
| 145 | symbolization_options = optparse.OptionGroup(parser, 'Symbolization Options') |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 146 | |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 147 | symbolization_options.add_option( |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 148 | '--breakpad_output_dir', |
| 149 | help='Optional path to empty directory to store fetched trace symbols ' |
| 150 | 'and extracted breakpad symbol files for official builds. Useful ' |
| 151 | 'for symbolizing multiple traces from the same Chrome build. Use ' |
| 152 | '--local_breakpad_dir when you already have breakpad files fetched. ' |
| 153 | 'Automatically uses temporary directory if flag not specified.', |
| 154 | dest='breakpad_output_dir') |
| 155 | symbolization_options.add_option( |
| 156 | '--local_breakpad_dir', |
| 157 | help='Optional path to local directory containing breakpad symbol files ' |
| 158 | 'used to symbolize the given trace. Breakpad files should be named ' |
| 159 | 'with module id in upper case hexadecimal and ".breakpad" ' |
| 160 | 'suffix. Ex: 12EFA32BE.breakpad', |
| 161 | dest='local_breakpad_dir') |
| 162 | symbolization_options.add_option( |
| 163 | '--local_build_dir', |
| 164 | help='Optional path to a local build directory containing symbol files.', |
| 165 | dest='local_build_dir') |
| 166 | symbolization_options.add_option( |
| 167 | '--dump_syms', |
ssid | 2266735 | 2021-11-29 21:06:53 | [diff] [blame] | 168 | help=('Path to a dump_syms binary. Required when symbolizing an official ' |
| 169 | 'build. Optional on local builds as we can use --local_build_dir ' |
| 170 | 'to locate a binary. If built locally with ' |
| 171 | 'autoninja -C out/Release dump_syms then the binary path is ' |
| 172 | 'out/Release/dump_syms'), |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 173 | dest='dump_syms_path') |
| 174 | symbolization_options.add_option( |
| 175 | '--symbolizer', |
| 176 | help=('Path to the trace_to_text binary for symbolization. Defaults to ' |
| 177 | '"third_party/perfetto/tools/traceconv". traceconv is the same as ' |
| 178 | 'trace_to_text, except that tracevonv finds a prebuilt ' |
| 179 | 'trace_to_text binary to use.'), |
| 180 | default='third_party/perfetto/tools/traceconv', |
| 181 | dest='symbolizer_path') |
| 182 | symbolization_options.add_option( |
| 183 | '--trace_processor', |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 184 | help=('Optional path to trace processor binary. ' |
| 185 | 'Automatically downloads binary if flag not specified.'), |
| 186 | dest='trace_processor_path') |
| 187 | symbolization_options.add_option( |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 188 | '--cloud_storage_bucket', |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 189 | help=('Optional cloud storage bucket to where symbol files reside. ' |
Uwem Wilson | 5239688 | 2021-07-23 14:54:03 | [diff] [blame] | 190 | 'Defaults to "chrome-unsigned".'), |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 191 | default='chrome-unsigned', |
| 192 | dest='cloud_storage_bucket') |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 193 | |
| 194 | return symbolization_options |
| 195 | |
| 196 | |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 197 | def SetupProfilingCategories(options): |
| 198 | """Sets --chrome_categories flag. |
| 199 | |
| 200 | Uses the --enable_profile flag to modify the --chrome_categories flag for |
| 201 | specific profiling options. |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 202 | |
| 203 | Args: |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 204 | options: The command-line options given. |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 205 | """ |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 206 | if options.enable_profiler is None: |
ssid | 2266735 | 2021-11-29 21:06:53 | [diff] [blame] | 207 | if not options.chrome_categories: |
| 208 | GetTracingLogger().warning( |
| 209 | 'No trace category or profiler is enabled using --enable_profiler ' |
| 210 | 'and/or --chrome_categories, enabling all default categories.') |
| 211 | if not options.skip_symbolize: |
| 212 | GetTracingLogger().warning( |
| 213 | 'No profiler is enabled, symbolization might fail without any ' |
| 214 | 'frames. Use --skip_symbolize to disable symbolization.') |
| 215 | else: |
| 216 | GetTracingLogger().info( |
| 217 | 'No profiler is enabled, the trace will only have trace events.') |
Ryan Huckleberry | dd9912c | 2021-08-03 19:19:00 | [diff] [blame] | 218 | return |
| 219 | |
| 220 | if options.chrome_categories is None: |
| 221 | options.chrome_categories = '' |
| 222 | profile_options = options.enable_profiler.split(',') |
| 223 | # Add to the --chrome_categories flag. |
| 224 | if 'cpu' in profile_options: |
| 225 | if options.chrome_categories: |
| 226 | options.chrome_categories += ',' |
| 227 | options.chrome_categories += 'disabled-by-default-cpu_profiler' |
| 228 | if 'memory' in profile_options: |
| 229 | if options.chrome_categories: |
| 230 | options.chrome_categories += ',disabled-by-default-memory-infra' |
| 231 | else: |
| 232 | # If heap profiling is enabled and no categories are provided, it is |
| 233 | # usually not helpful to include other information in traces. '-*' |
| 234 | # disables other default categories so that only memory data is recorded. |
| 235 | options.chrome_categories += 'disabled-by-default-memory-infra,-*' |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 236 | |
| 237 | |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 238 | def GetTracingLogger(): |
| 239 | """Returns the logger for tools/tracing.""" |
| 240 | return logging.getLogger(TRACING_LOGGER_NAME) |
| 241 | |
| 242 | |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 243 | def SetupLogging(verbosity): |
| 244 | """Setup logging levels. |
| 245 | |
| 246 | Sets default level to warning. |
| 247 | |
| 248 | Args: |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 249 | verbosity: None or integer type that specifies the logging level. |
| 250 | (options.verbosity) |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 251 | """ |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 252 | logger = GetTracingLogger() |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 253 | if verbosity == 1: |
| 254 | logging.basicConfig(level=logging.INFO) |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 255 | logger.setLevel(level=logging.INFO) |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 256 | elif verbosity >= 2: |
| 257 | logging.basicConfig(level=logging.DEBUG) |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 258 | logger.setLevel(level=logging.DEBUG) |
Ryan Huckleberry | 679263c | 2021-07-16 21:59:01 | [diff] [blame] | 259 | else: |
| 260 | logging.basicConfig(level=logging.WARNING) |
ssid | 6568baad | 2021-11-23 21:46:45 | [diff] [blame] | 261 | logger.setLevel(level=logging.WARNING) |