blob: 1a9deb5bee37a01bbe5fbe297db8f6f9b155ffae [file] [log] [blame]
Ian Zernycbcd5032021-10-15 13:34:28 +02001#!/usr/bin/env python3
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +01002# 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 Zerny3af58152023-03-13 10:52:27 +01006from os import path
7
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +01008import argparse
Ian Zernycbcd5032021-10-15 13:34:28 +02009import os
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +010010import subprocess
11import sys
Ian Zerny9ff31b72021-04-22 11:36:26 +020012
Ian Zernycbcd5032021-10-15 13:34:28 +020013import jdk
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +010014import utils
15
Ian Zerny9ff31b72021-04-22 11:36:26 +020016
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010017def parse_arguments():
18 parser = argparse.ArgumentParser(
19 description = 'R8lib wrapper for retrace tool.')
20 parser.add_argument(
21 '-c',
Søren Gjesse8ebfddf2022-04-29 08:47:30 +020022 '--commit-hash',
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010023 '--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-Jespersen08701bf2019-12-02 21:31:04 +010031 '--tag',
32 help='Tag to download r8lib map file for.',
33 default=None)
34 parser.add_argument(
Søren Gjesse8ebfddf2022-04-29 08:47:30 +020035 '--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-Jespersena6f0f2f2019-01-17 13:57:39 +010040 '--map',
41 help='Path to r8lib map.',
Ian Zernycbcd5032021-10-15 13:34:28 +020042 default=None)
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010043 parser.add_argument(
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +020044 '--r8jar',
45 help='Path to r8 jar.',
46 default=None)
47 parser.add_argument(
Morten Krogh-Jespersen3aa4bff82020-09-30 16:43:26 +020048 '--no-r8lib',
Søren Gjesse8ebfddf2022-04-29 08:47:30 +020049 '--no_r8lib',
Morten Krogh-Jespersen3aa4bff82020-09-30 16:43:26 +020050 default=False,
51 action='store_true',
52 help='Use r8.jar and not r8lib.jar.')
53 parser.add_argument(
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010054 '--stacktrace',
Ian Zernycbcd5032021-10-15 13:34:28 +020055 help='Path to stacktrace file (read from stdin if not passed).',
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010056 default=None)
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +010057 parser.add_argument(
58 '--quiet',
59 default=None,
60 action='store_true',
61 help='Disables diagnostics printing to stdout.')
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +010062 parser.add_argument(
Morten Krogh-Jespersenb6b2eb52021-08-11 09:33:20 +020063 '--debug-agent',
Søren Gjesse8ebfddf2022-04-29 08:47:30 +020064 '--debug_agent',
Morten Krogh-Jespersenb6b2eb52021-08-11 09:33:20 +020065 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 Adamsen5e8f04e2021-09-24 08:48:31 +020073 parser.add_argument(
74 '--verbose',
75 default=None,
76 action='store_true',
77 help='Enables verbose retracing.')
Morten Krogh-Jespersenb4713b92022-01-27 13:35:17 +010078 parser.add_argument(
79 '--disable-map-validation',
80 default=None,
81 action='store_true',
82 help='Disable validation of map hash.')
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010083 return parser.parse_args()
84
85
Ian Zernycbcd5032021-10-15 13:34:28 +020086def 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 Zernycf8ef512022-05-04 14:54:16 +0200119 # 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 Zernycbcd5032021-10-15 13:34:28 +0200126 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 Zerny3af58152023-03-13 10:52:27 +0100131 if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(utils.R8LIB_MAP) == maphash:
Rico Wind158ef9f2022-05-19 11:08:30 +0200132 return utils.R8LIB_MAP
133
Ian Zernycbcd5032021-10-15 13:34:28 +0200134 try:
Søren Gjesse8ebfddf2022-04-29 08:47:30 +0200135 map_path = utils.find_cloud_storage_file_from_options(
Ian Zernycf8ef512022-05-04 14:54:16 +0200136 'r8lib' + ('-exclude-deps' if is_excldeps else '') + '.jar.map', args)
Ian Zernycbcd5032021-10-15 13:34:28 +0200137 except Exception as e:
138 print(e)
139 print('WARNING: Falling back to using local mapping file.')
140
Morten Krogh-Jespersenb4713b92022-01-27 13:35:17 +0100141 if map_path and not args.disable_map_validation:
Søren Gjesse8ebfddf2022-04-29 08:47:30 +0200142 check_maphash(map_path, maphash, args)
Ian Zernycbcd5032021-10-15 13:34:28 +0200143 return map_path
144
145 # If no other map file was found, use the local mapping file.
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +0200146 if args.r8jar:
147 return args.r8jar + ".map"
Rico Wind158ef9f2022-05-19 11:08:30 +0200148 return utils.R8LIB_MAP
Ian Zernycbcd5032021-10-15 13:34:28 +0200149
150
Søren Gjesse8ebfddf2022-04-29 08:47:30 +0200151def check_maphash(mapping_path, maphash, args):
Rico Wind158ef9f2022-05-19 11:08:30 +0200152 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
162def get_hash_from_map_file(mapping_path):
Ian Zernycbcd5032021-10-15 13:34:28 +0200163 map_hash_header = "# pg_map_hash: SHA-256 "
164 for line in open(mapping_path, 'r'):
165 if line.startswith(map_hash_header):
Rico Wind158ef9f2022-05-19 11:08:30 +0200166 return line[len(map_hash_header):].strip()
Ian Zernycbcd5032021-10-15 13:34:28 +0200167
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +0100168def main():
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +0100169 args = parse_arguments()
Ian Zernycbcd5032021-10-15 13:34:28 +0200170 with utils.TempDir() as temp:
171 map_path = get_map_file(args, temp)
172 return run(
Christoffer Quist Adamsen4d38d032021-04-20 12:31:31 +0200173 map_path,
Morten Krogh-Jespersen3aa4bff82020-09-30 16:43:26 +0200174 args.stacktrace,
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +0200175 args.r8jar,
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +0100176 args.no_r8lib,
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +0100177 quiet=args.quiet,
Morten Krogh-Jespersenb6b2eb52021-08-11 09:33:20 +0200178 debug=args.debug_agent,
Christoffer Quist Adamsen5e8f04e2021-09-24 08:48:31 +0200179 regex=args.regex,
180 verbose=args.verbose)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100181
Ian Zernycbcd5032021-10-15 13:34:28 +0200182
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +0200183def run(map_path, stacktrace, r8jar, no_r8lib, quiet=False, debug=False, regex=None, verbose=False):
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +0100184 retrace_args = [jdk.GetJavaExecutable()]
185
186 if debug:
Christoffer Quist Adamsen4d38d032021-04-20 12:31:31 +0200187 retrace_args.append(
188 '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005')
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +0100189
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +0200190 if not r8jar:
191 r8jar = utils.R8_JAR if no_r8lib else utils.R8RETRACE_JAR
192
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +0100193 retrace_args += [
Morten Krogh-Jespersen89a5b062020-01-07 14:50:40 +0100194 '-cp',
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +0200195 r8jar,
Morten Krogh-Jespersen89a5b062020-01-07 14:50:40 +0100196 'com.android.tools.r8.retrace.Retrace',
Morten Krogh-Jespersen3aa4bff82020-09-30 16:43:26 +0200197 map_path
Ian Zerny3f54e222019-02-12 10:51:17 +0100198 ]
Morten Krogh-Jespersen89a5b062020-01-07 14:50:40 +0100199
Morten Krogh-Jespersenb6b2eb52021-08-11 09:33:20 +0200200 if regex:
201 retrace_args.append('--regex')
202 retrace_args.append(regex)
203
Morten Krogh-Jespersen691793a2021-01-08 11:36:20 +0100204 if quiet:
205 retrace_args.append('--quiet')
206
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100207 if stacktrace:
208 retrace_args.append(stacktrace)
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +0100209
Christoffer Quist Adamsen5e8f04e2021-09-24 08:48:31 +0200210 if verbose:
211 retrace_args.append('--verbose')
212
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +0100213 utils.PrintCmd(retrace_args, quiet=quiet)
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +0100214 return subprocess.call(retrace_args)
215
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +0100216
217if __name__ == '__main__':
218 sys.exit(main())