blob: 9768ff3e658a6fe7061a96b9bc7458d5a76d14e2 [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():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020018 parser = argparse.ArgumentParser(
19 description='R8lib wrapper for retrace tool.')
20 parser.add_argument('-c',
21 '--commit-hash',
22 '--commit_hash',
23 help='Commit hash to download r8lib map file for.',
24 default=None)
25 parser.add_argument('--version',
26 help='Version to download r8lib map file for.',
27 default=None)
28 parser.add_argument('--tag',
29 help='Tag to download r8lib map file for.',
30 default=None)
31 parser.add_argument(
32 '--exclude-deps',
33 '--exclude_deps',
34 default=None,
35 action='store_true',
36 help='Use the exclude-deps version of the mapping file.')
37 parser.add_argument('--map', help='Path to r8lib map.', default=None)
38 parser.add_argument('--r8jar', help='Path to r8 jar.', default=None)
39 parser.add_argument('--no-r8lib',
40 '--no_r8lib',
41 default=False,
42 action='store_true',
43 help='Use r8.jar and not r8lib.jar.')
44 parser.add_argument(
45 '--stacktrace',
46 help='Path to stacktrace file (read from stdin if not passed).',
47 default=None)
48 parser.add_argument('--quiet',
49 default=None,
50 action='store_true',
51 help='Disables diagnostics printing to stdout.')
52 parser.add_argument(
53 '--debug-agent',
54 '--debug_agent',
55 default=None,
56 action='store_true',
57 help='Attach a debug-agent to the retracer java process.')
58 parser.add_argument(
59 '--regex',
60 default=None,
61 help='Sets a custom regular expression used for parsing')
62 parser.add_argument('--verbose',
63 default=None,
64 action='store_true',
65 help='Enables verbose retracing.')
66 parser.add_argument('--disable-map-validation',
67 default=None,
68 action='store_true',
69 help='Disable validation of map hash.')
70 return parser.parse_args()
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +010071
72
Ian Zernycbcd5032021-10-15 13:34:28 +020073def get_map_file(args, temp):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020074 # default to using the specified map file.
75 if args.map:
76 return args.map
Ian Zernycbcd5032021-10-15 13:34:28 +020077
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020078 # next try to extract it from the tag/version options.
79 map_path = utils.find_cloud_storage_file_from_options('r8lib.jar.map', args)
80 if map_path:
81 return map_path
Ian Zernycbcd5032021-10-15 13:34:28 +020082
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020083 # next try to extract it from the stack-trace source-file content.
84 if not args.stacktrace:
85 if not args.quiet:
86 print('Waiting for stack-trace input...')
87 args.stacktrace = os.path.join(temp, 'stacktrace.txt')
88 open(args.stacktrace, 'w').writelines(sys.stdin.readlines())
Ian Zernycbcd5032021-10-15 13:34:28 +020089
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020090 r8_source_file = None
91 for line in open(args.stacktrace, 'r'):
92 start = line.rfind("(R8_")
93 if start > 0:
94 end = line.find(":", start)
95 content = line[start + 1:end]
96 if r8_source_file:
97 if content != r8_source_file:
98 print(
99 'WARNING: there are multiple distinct R8 source files:')
100 print(' ' + r8_source_file)
101 print(' ' + content)
102 else:
103 r8_source_file = content
Ian Zernycbcd5032021-10-15 13:34:28 +0200104
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200105 if r8_source_file:
106 (header, r8_version_or_hash, maphash) = r8_source_file.split('_')
107 # If the command-line specified --exclude-deps then assume it is as previous
108 # versions will not be marked as such in the source-file line.
109 is_excldeps = args.exclude_deps
110 excldeps_start = r8_version_or_hash.find('+excldeps')
111 if (excldeps_start > 0):
112 is_excldeps = True
113 r8_version_or_hash = r8_version_or_hash[0:excldeps_start]
114 if len(r8_version_or_hash) < 40:
115 args.version = r8_version_or_hash
116 else:
117 args.commit_hash = r8_version_or_hash
118 map_path = None
119 if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(
120 utils.R8LIB_MAP) == maphash:
121 return utils.R8LIB_MAP
Rico Wind158ef9f2022-05-19 11:08:30 +0200122
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200123 try:
124 map_path = utils.find_cloud_storage_file_from_options(
125 'r8lib' + ('-exclude-deps' if is_excldeps else '') + '.jar.map',
126 args)
127 except Exception as e:
128 print(e)
129 print('WARNING: Falling back to using local mapping file.')
Ian Zernycbcd5032021-10-15 13:34:28 +0200130
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200131 if map_path and not args.disable_map_validation:
132 check_maphash(map_path, maphash, args)
133 return map_path
Ian Zernycbcd5032021-10-15 13:34:28 +0200134
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200135 # If no other map file was found, use the local mapping file.
136 if args.r8jar:
137 return args.r8jar + ".map"
138 return utils.R8LIB_MAP
Ian Zernycbcd5032021-10-15 13:34:28 +0200139
140
Søren Gjesse8ebfddf2022-04-29 08:47:30 +0200141def check_maphash(mapping_path, maphash, args):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200142 infile_maphash = get_hash_from_map_file(mapping_path)
143 if infile_maphash != maphash:
144 print('ERROR: The mapping file hash does not match the R8 line')
145 print(' In mapping file: ' + infile_maphash)
146 print(' In source file: ' + maphash)
147 if (not args.exclude_deps):
148 print(
149 'If this could be a version without internalized dependencies '
150 + 'try passing --exclude-deps')
151 sys.exit(1)
152
Rico Wind158ef9f2022-05-19 11:08:30 +0200153
154def get_hash_from_map_file(mapping_path):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200155 map_hash_header = "# pg_map_hash: SHA-256 "
156 for line in open(mapping_path, 'r'):
157 if line.startswith(map_hash_header):
158 return line[len(map_hash_header):].strip()
159
Ian Zernycbcd5032021-10-15 13:34:28 +0200160
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +0100161def main():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200162 args = parse_arguments()
163 with utils.TempDir() as temp:
164 map_path = get_map_file(args, temp)
165 return run(map_path,
166 args.stacktrace,
167 args.r8jar,
168 args.no_r8lib,
169 quiet=args.quiet,
170 debug=args.debug_agent,
171 regex=args.regex,
172 verbose=args.verbose)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100173
Ian Zernycbcd5032021-10-15 13:34:28 +0200174
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200175def run(map_path,
176 stacktrace,
177 r8jar,
178 no_r8lib,
179 quiet=False,
180 debug=False,
181 regex=None,
182 verbose=False):
183 retrace_args = [jdk.GetJavaExecutable()]
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +0100184
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200185 if debug:
186 retrace_args.append(
187 '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005'
188 )
Morten Krogh-Jespersenc9fd21d2020-12-14 09:25:11 +0100189
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200190 if not r8jar:
Christoffer Quist Adamsen5a0a5102023-11-09 08:33:14 +0100191 r8jar = utils.R8_JAR if no_r8lib else utils.R8LIB_JAR
Morten Krogh-Jespersenf984cf12023-09-10 22:48:44 +0200192
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200193 retrace_args += [
194 '-cp', r8jar, 'com.android.tools.r8.retrace.Retrace', map_path
195 ]
Morten Krogh-Jespersen89a5b062020-01-07 14:50:40 +0100196
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200197 if regex:
198 retrace_args.append('--regex')
199 retrace_args.append(regex)
Morten Krogh-Jespersenb6b2eb52021-08-11 09:33:20 +0200200
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200201 if quiet:
202 retrace_args.append('--quiet')
Morten Krogh-Jespersen691793a2021-01-08 11:36:20 +0100203
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200204 if stacktrace:
205 retrace_args.append(stacktrace)
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +0100206
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200207 if verbose:
208 retrace_args.append('--verbose')
Christoffer Quist Adamsen5e8f04e2021-09-24 08:48:31 +0200209
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200210 utils.PrintCmd(retrace_args, quiet=quiet)
211 return subprocess.call(retrace_args)
Morten Krogh-Jespersena6f0f2f2019-01-17 13:57:39 +0100212
Morten Krogh-Jespersen017a7002019-01-10 14:14:17 +0100213
214if __name__ == '__main__':
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200215 sys.exit(main())