Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Morten Krogh-Jespersen | 017a700 | 2019-01-10 14:14:17 +0100 | [diff] [blame] | 2 | # Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file |
| 3 | # for details. All rights reserved. Use of this source code is governed by a |
| 4 | # BSD-style license that can be found in the LICENSE file. |
| 5 | |
Ian Zerny | 3af5815 | 2023-03-13 10:52:27 +0100 | [diff] [blame] | 6 | from os import path |
| 7 | |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 8 | import argparse |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 9 | import os |
Morten Krogh-Jespersen | 017a700 | 2019-01-10 14:14:17 +0100 | [diff] [blame] | 10 | import subprocess |
| 11 | import sys |
Ian Zerny | 9ff31b7 | 2021-04-22 11:36:26 +0200 | [diff] [blame] | 12 | |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 13 | import jdk |
Morten Krogh-Jespersen | 017a700 | 2019-01-10 14:14:17 +0100 | [diff] [blame] | 14 | import utils |
| 15 | |
Ian Zerny | 9ff31b7 | 2021-04-22 11:36:26 +0200 | [diff] [blame] | 16 | |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 17 | def parse_arguments(): |
| 18 | parser = argparse.ArgumentParser( |
| 19 | description = 'R8lib wrapper for retrace tool.') |
| 20 | parser.add_argument( |
| 21 | '-c', |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 22 | '--commit-hash', |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 23 | '--commit_hash', |
| 24 | help='Commit hash to download r8lib map file for.', |
| 25 | default=None) |
| 26 | parser.add_argument( |
| 27 | '--version', |
| 28 | help='Version to download r8lib map file for.', |
| 29 | default=None) |
| 30 | parser.add_argument( |
Morten Krogh-Jespersen | 08701bf | 2019-12-02 21:31:04 +0100 | [diff] [blame] | 31 | '--tag', |
| 32 | help='Tag to download r8lib map file for.', |
| 33 | default=None) |
| 34 | parser.add_argument( |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 35 | '--exclude-deps', '--exclude_deps', |
| 36 | default=None, |
| 37 | action='store_true', |
| 38 | help='Use the exclude-deps version of the mapping file.') |
| 39 | parser.add_argument( |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 40 | '--map', |
| 41 | help='Path to r8lib map.', |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 42 | default=None) |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 43 | parser.add_argument( |
Morten Krogh-Jespersen | f984cf1 | 2023-09-10 22:48:44 +0200 | [diff] [blame] | 44 | '--r8jar', |
| 45 | help='Path to r8 jar.', |
| 46 | default=None) |
| 47 | parser.add_argument( |
Morten Krogh-Jespersen | 3aa4bff8 | 2020-09-30 16:43:26 +0200 | [diff] [blame] | 48 | '--no-r8lib', |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 49 | '--no_r8lib', |
Morten Krogh-Jespersen | 3aa4bff8 | 2020-09-30 16:43:26 +0200 | [diff] [blame] | 50 | default=False, |
| 51 | action='store_true', |
| 52 | help='Use r8.jar and not r8lib.jar.') |
| 53 | parser.add_argument( |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 54 | '--stacktrace', |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 55 | help='Path to stacktrace file (read from stdin if not passed).', |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 56 | default=None) |
Christoffer Quist Adamsen | 7bf6034 | 2020-11-09 14:00:27 +0100 | [diff] [blame] | 57 | parser.add_argument( |
| 58 | '--quiet', |
| 59 | default=None, |
| 60 | action='store_true', |
| 61 | help='Disables diagnostics printing to stdout.') |
Morten Krogh-Jespersen | c9fd21d | 2020-12-14 09:25:11 +0100 | [diff] [blame] | 62 | parser.add_argument( |
Morten Krogh-Jespersen | b6b2eb5 | 2021-08-11 09:33:20 +0200 | [diff] [blame] | 63 | '--debug-agent', |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 64 | '--debug_agent', |
Morten Krogh-Jespersen | b6b2eb5 | 2021-08-11 09:33:20 +0200 | [diff] [blame] | 65 | default=None, |
| 66 | action='store_true', |
| 67 | help='Attach a debug-agent to the retracer java process.') |
| 68 | parser.add_argument( |
| 69 | '--regex', |
| 70 | default=None, |
| 71 | help='Sets a custom regular expression used for parsing' |
| 72 | ) |
Christoffer Quist Adamsen | 5e8f04e | 2021-09-24 08:48:31 +0200 | [diff] [blame] | 73 | parser.add_argument( |
| 74 | '--verbose', |
| 75 | default=None, |
| 76 | action='store_true', |
| 77 | help='Enables verbose retracing.') |
Morten Krogh-Jespersen | b4713b9 | 2022-01-27 13:35:17 +0100 | [diff] [blame] | 78 | parser.add_argument( |
| 79 | '--disable-map-validation', |
| 80 | default=None, |
| 81 | action='store_true', |
| 82 | help='Disable validation of map hash.') |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 83 | return parser.parse_args() |
| 84 | |
| 85 | |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 86 | def get_map_file(args, temp): |
| 87 | # default to using the specified map file. |
| 88 | if args.map: |
| 89 | return args.map |
| 90 | |
| 91 | # next try to extract it from the tag/version options. |
| 92 | map_path = utils.find_cloud_storage_file_from_options('r8lib.jar.map', args) |
| 93 | if map_path: |
| 94 | return map_path |
| 95 | |
| 96 | # next try to extract it from the stack-trace source-file content. |
| 97 | if not args.stacktrace: |
| 98 | if not args.quiet: |
| 99 | print('Waiting for stack-trace input...') |
| 100 | args.stacktrace = os.path.join(temp, 'stacktrace.txt') |
| 101 | open(args.stacktrace, 'w').writelines(sys.stdin.readlines()) |
| 102 | |
| 103 | r8_source_file = None |
| 104 | for line in open(args.stacktrace, 'r'): |
| 105 | start = line.rfind("(R8_") |
| 106 | if start > 0: |
| 107 | end = line.find(":", start) |
| 108 | content = line[start + 1: end] |
| 109 | if r8_source_file: |
| 110 | if content != r8_source_file: |
| 111 | print('WARNING: there are multiple distinct R8 source files:') |
| 112 | print(' ' + r8_source_file) |
| 113 | print(' ' + content) |
| 114 | else: |
| 115 | r8_source_file = content |
| 116 | |
| 117 | if r8_source_file: |
| 118 | (header, r8_version_or_hash, maphash) = r8_source_file.split('_') |
Ian Zerny | cf8ef51 | 2022-05-04 14:54:16 +0200 | [diff] [blame] | 119 | # If the command-line specified --exclude-deps then assume it is as previous |
| 120 | # versions will not be marked as such in the source-file line. |
| 121 | is_excldeps = args.exclude_deps |
| 122 | excldeps_start = r8_version_or_hash.find('+excldeps') |
| 123 | if (excldeps_start > 0): |
| 124 | is_excldeps = True |
| 125 | r8_version_or_hash = r8_version_or_hash[0:excldeps_start] |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 126 | if len(r8_version_or_hash) < 40: |
| 127 | args.version = r8_version_or_hash |
| 128 | else: |
| 129 | args.commit_hash = r8_version_or_hash |
| 130 | map_path = None |
Ian Zerny | 3af5815 | 2023-03-13 10:52:27 +0100 | [diff] [blame] | 131 | if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(utils.R8LIB_MAP) == maphash: |
Rico Wind | 158ef9f | 2022-05-19 11:08:30 +0200 | [diff] [blame] | 132 | return utils.R8LIB_MAP |
| 133 | |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 134 | try: |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 135 | map_path = utils.find_cloud_storage_file_from_options( |
Ian Zerny | cf8ef51 | 2022-05-04 14:54:16 +0200 | [diff] [blame] | 136 | 'r8lib' + ('-exclude-deps' if is_excldeps else '') + '.jar.map', args) |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 137 | except Exception as e: |
| 138 | print(e) |
| 139 | print('WARNING: Falling back to using local mapping file.') |
| 140 | |
Morten Krogh-Jespersen | b4713b9 | 2022-01-27 13:35:17 +0100 | [diff] [blame] | 141 | if map_path and not args.disable_map_validation: |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 142 | check_maphash(map_path, maphash, args) |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 143 | return map_path |
| 144 | |
| 145 | # If no other map file was found, use the local mapping file. |
Morten Krogh-Jespersen | f984cf1 | 2023-09-10 22:48:44 +0200 | [diff] [blame] | 146 | if args.r8jar: |
| 147 | return args.r8jar + ".map" |
Rico Wind | 158ef9f | 2022-05-19 11:08:30 +0200 | [diff] [blame] | 148 | return utils.R8LIB_MAP |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 149 | |
| 150 | |
Søren Gjesse | 8ebfddf | 2022-04-29 08:47:30 +0200 | [diff] [blame] | 151 | def check_maphash(mapping_path, maphash, args): |
Rico Wind | 158ef9f | 2022-05-19 11:08:30 +0200 | [diff] [blame] | 152 | infile_maphash = get_hash_from_map_file(mapping_path) |
| 153 | if infile_maphash != maphash: |
| 154 | print('ERROR: The mapping file hash does not match the R8 line') |
| 155 | print(' In mapping file: ' + infile_maphash) |
| 156 | print(' In source file: ' + maphash) |
| 157 | if (not args.exclude_deps): |
| 158 | print('If this could be a version without internalized dependencies ' |
| 159 | + 'try passing --exclude-deps') |
| 160 | sys.exit(1) |
| 161 | |
| 162 | def get_hash_from_map_file(mapping_path): |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 163 | map_hash_header = "# pg_map_hash: SHA-256 " |
| 164 | for line in open(mapping_path, 'r'): |
| 165 | if line.startswith(map_hash_header): |
Rico Wind | 158ef9f | 2022-05-19 11:08:30 +0200 | [diff] [blame] | 166 | return line[len(map_hash_header):].strip() |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 167 | |
Morten Krogh-Jespersen | 017a700 | 2019-01-10 14:14:17 +0100 | [diff] [blame] | 168 | def main(): |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 169 | args = parse_arguments() |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 170 | with utils.TempDir() as temp: |
| 171 | map_path = get_map_file(args, temp) |
| 172 | return run( |
Christoffer Quist Adamsen | 4d38d03 | 2021-04-20 12:31:31 +0200 | [diff] [blame] | 173 | map_path, |
Morten Krogh-Jespersen | 3aa4bff8 | 2020-09-30 16:43:26 +0200 | [diff] [blame] | 174 | args.stacktrace, |
Morten Krogh-Jespersen | f984cf1 | 2023-09-10 22:48:44 +0200 | [diff] [blame] | 175 | args.r8jar, |
Christoffer Quist Adamsen | 7bf6034 | 2020-11-09 14:00:27 +0100 | [diff] [blame] | 176 | args.no_r8lib, |
Morten Krogh-Jespersen | c9fd21d | 2020-12-14 09:25:11 +0100 | [diff] [blame] | 177 | quiet=args.quiet, |
Morten Krogh-Jespersen | b6b2eb5 | 2021-08-11 09:33:20 +0200 | [diff] [blame] | 178 | debug=args.debug_agent, |
Christoffer Quist Adamsen | 5e8f04e | 2021-09-24 08:48:31 +0200 | [diff] [blame] | 179 | regex=args.regex, |
| 180 | verbose=args.verbose) |
Ian Zerny | 5ffa58f | 2020-02-26 08:37:14 +0100 | [diff] [blame] | 181 | |
Ian Zerny | cbcd503 | 2021-10-15 13:34:28 +0200 | [diff] [blame] | 182 | |
Morten Krogh-Jespersen | f984cf1 | 2023-09-10 22:48:44 +0200 | [diff] [blame] | 183 | def run(map_path, stacktrace, r8jar, no_r8lib, quiet=False, debug=False, regex=None, verbose=False): |
Morten Krogh-Jespersen | c9fd21d | 2020-12-14 09:25:11 +0100 | [diff] [blame] | 184 | retrace_args = [jdk.GetJavaExecutable()] |
| 185 | |
| 186 | if debug: |
Christoffer Quist Adamsen | 4d38d03 | 2021-04-20 12:31:31 +0200 | [diff] [blame] | 187 | retrace_args.append( |
| 188 | '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005') |
Morten Krogh-Jespersen | c9fd21d | 2020-12-14 09:25:11 +0100 | [diff] [blame] | 189 | |
Morten Krogh-Jespersen | f984cf1 | 2023-09-10 22:48:44 +0200 | [diff] [blame] | 190 | if not r8jar: |
| 191 | r8jar = utils.R8_JAR if no_r8lib else utils.R8RETRACE_JAR |
| 192 | |
Morten Krogh-Jespersen | c9fd21d | 2020-12-14 09:25:11 +0100 | [diff] [blame] | 193 | retrace_args += [ |
Morten Krogh-Jespersen | 89a5b06 | 2020-01-07 14:50:40 +0100 | [diff] [blame] | 194 | '-cp', |
Morten Krogh-Jespersen | f984cf1 | 2023-09-10 22:48:44 +0200 | [diff] [blame] | 195 | r8jar, |
Morten Krogh-Jespersen | 89a5b06 | 2020-01-07 14:50:40 +0100 | [diff] [blame] | 196 | 'com.android.tools.r8.retrace.Retrace', |
Morten Krogh-Jespersen | 3aa4bff8 | 2020-09-30 16:43:26 +0200 | [diff] [blame] | 197 | map_path |
Ian Zerny | 3f54e22 | 2019-02-12 10:51:17 +0100 | [diff] [blame] | 198 | ] |
Morten Krogh-Jespersen | 89a5b06 | 2020-01-07 14:50:40 +0100 | [diff] [blame] | 199 | |
Morten Krogh-Jespersen | b6b2eb5 | 2021-08-11 09:33:20 +0200 | [diff] [blame] | 200 | if regex: |
| 201 | retrace_args.append('--regex') |
| 202 | retrace_args.append(regex) |
| 203 | |
Morten Krogh-Jespersen | 691793a | 2021-01-08 11:36:20 +0100 | [diff] [blame] | 204 | if quiet: |
| 205 | retrace_args.append('--quiet') |
| 206 | |
Ian Zerny | 5ffa58f | 2020-02-26 08:37:14 +0100 | [diff] [blame] | 207 | if stacktrace: |
| 208 | retrace_args.append(stacktrace) |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 209 | |
Christoffer Quist Adamsen | 5e8f04e | 2021-09-24 08:48:31 +0200 | [diff] [blame] | 210 | if verbose: |
| 211 | retrace_args.append('--verbose') |
| 212 | |
Christoffer Quist Adamsen | 7bf6034 | 2020-11-09 14:00:27 +0100 | [diff] [blame] | 213 | utils.PrintCmd(retrace_args, quiet=quiet) |
Morten Krogh-Jespersen | a6f0f2f | 2019-01-17 13:57:39 +0100 | [diff] [blame] | 214 | return subprocess.call(retrace_args) |
| 215 | |
Morten Krogh-Jespersen | 017a700 | 2019-01-10 14:14:17 +0100 | [diff] [blame] | 216 | |
| 217 | if __name__ == '__main__': |
| 218 | sys.exit(main()) |