| #!/usr/bin/env python3 |
| # |
| # 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. |
| |
| 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')) |
| import breakpad_file_extractor |
| import flag_utils |
| import metadata_extractor |
| import symbol_fetcher |
| import get_symbols_util |
| |
| _DESCRIPTION = ( |
| """Fetches symbol files for Android official builds, need access to the storage. |
| Useful to symbolize crashes. You can find the version number and version code |
| in the bug reports or stack trace. Version number is commonly used Chrome |
| Version, like "93.0.4606.0" and version code is play store version code, a 9-10 |
| digit number starting with branch number, 460601633. Module ID can be seen from |
| unsymbolized stack trace, a 32 character hex string in upper case. You need to |
| build dump_syms in your local output dir to use module ID matcher. In any |
| Android output directory with same arch (arm), build dump_syms by using |
| ninja -C out-android/Release dump_syms. |
| """) |
| |
| _USAGE = """ |
| tools/tracing/get_clank_symbols --version=<> --version_code=<> \\ |
| --arch={arm/x86} --module_id=<ABC123> \\ |
| --dump_syms=<out-android/Release/dupm_syms> -v |
| |
| optional: |
| --arch={arm/x86} |
| --output=/tmp/output_dir/ |
| """ |
| |
| |
| def _CreateOptionParser(): |
| parser = optparse.OptionParser( |
| description=_DESCRIPTION, usage=_USAGE, conflict_handler='resolve') |
| |
| parser.add_option_group(flag_utils.GeneralOptions(parser)) |
| parser.add_option_group(flag_utils.SymbolizeOptions(parser)) |
| |
| parser.add_option('--version', dest='version') |
| parser.add_option('--version_code', dest='version_code') |
| parser.add_option('--module_id', dest='module_id') |
| parser.add_option('--arch', dest='arch', default='arm64') |
| parser.add_option('--output', dest='output', default='/tmp/symbols') |
| |
| return parser |
| |
| |
| def main(): |
| parser = _CreateOptionParser() |
| options, _ = parser.parse_args() |
| |
| flag_utils.SetupLogging(options.verbosity) |
| logger = flag_utils.GetTracingLogger() |
| |
| if not options.version or not options.version_code: |
| raise Exception('Both Chrome --version and --version_code are necessary to ' |
| 'fetch symbols.') |
| |
| metadata = metadata_extractor.MetadataExtractor(None, None) |
| metadata.os_name = 'android' |
| metadata.version_number = options.version |
| metadata.version_code = options.version_code |
| metadata.architecture = options.arch |
| |
| if options.module_id: |
| if not options.dump_syms_path: |
| raise Exception('Path to dump_syms binary is required for symbolizing ' |
| 'official Android traces. You can build dump_syms from ' |
| 'your local build directory with the right architecture ' |
| 'with: autoninja -C out_<arch>/Release dump_syms.') |
| |
| if os.path.isdir(options.output): |
| logger.warning( |
| 'The output directory %s exists, and new files will overwrite the old ' |
| 'ones.', options.output) |
| |
| print( |
| 'Downloading all symbols for the version, please wait up to 5 minutes...') |
| symbol_fetcher.GetAndroidSymbols(options.cloud_storage_bucket, metadata, |
| options.output) |
| |
| if not options.module_id: |
| print('All symbols downloaded to ' + options.output) |
| return |
| |
| found_module = get_symbols_util.FindMatchingModule(options.output, |
| options.dump_syms_path, |
| options.module_id) |
| if found_module: |
| print('Found symbol file with module ID: %s and saved to %s. Use this ' |
| 'directory for symbolization' % (options.module_id, found_module)) |
| else: |
| logger.error( |
| 'No modules with the module ID %s found. All symbols for the specified ' |
| 'version are saved to %s', (options.module_id, options.output)) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |
| |