| #!/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()) | 
 |  |