Add support for partition map in retrace script
Look for the partition map in the ZIP format first and otherwise
fallback to the text mapping file.
Change-Id: I3a72cfdcdf52a5162b8e1c81fd80297f3d7f38c7
diff --git a/tools/retrace.py b/tools/retrace.py
index 9768ff3..22cab9a 100755
--- a/tools/retrace.py
+++ b/tools/retrace.py
@@ -34,7 +34,11 @@
default=None,
action='store_true',
help='Use the exclude-deps version of the mapping file.')
- parser.add_argument('--map', help='Path to r8lib map.', default=None)
+ parser.add_argument('--map', help='Path to r8lib map in text format.', default=None)
+ parser.add_argument('--partition-map',
+ '--partition_map',
+ help='Path to r8lib map in ZIP partition format.',
+ default=None)
parser.add_argument('--r8jar', help='Path to r8 jar.', default=None)
parser.add_argument('--no-r8lib',
'--no_r8lib',
@@ -67,28 +71,47 @@
default=None,
action='store_true',
help='Disable validation of map hash.')
+ parser.add_argument(
+ '--disable-partition-map',
+ default=False,
+ action='store_true',
+ help='Disable use of partition map (unless one was explicitly specified'
+ ' with --partition-map).')
return parser.parse_args()
def get_map_file(args, temp):
- # default to using the specified map file.
+ # Default to using the specified map file.
if args.map:
- return args.map
+ return (False, args.map)
+ if args.partition_map:
+ return (True, args.partition_map)
- # next try to extract it from the tag/version options.
- map_path = utils.find_cloud_storage_file_from_options('r8lib.jar.map', args)
- if map_path:
- return map_path
+ for use_partition_map in ([False] if args.disable_partition_map else [True, False]):
+ # Try to extract map from the tag/version options.
+ map_path = utils.find_cloud_storage_file_from_options(
+ 'r8lib.jar_map.zip' if use_partition_map else 'r8lib.jar.map', args)
+ if map_path:
+ return (use_partition_map, map_path)
- # next try to extract it from the stack-trace source-file content.
- if not args.stacktrace:
- if not args.quiet:
- print('Waiting for stack-trace input...')
- args.stacktrace = os.path.join(temp, 'stacktrace.txt')
- open(args.stacktrace, 'w').writelines(sys.stdin.readlines())
+ # Try to extract map from the stack-trace source-file content.
+ r8_source_file = get_r8_source_file_attribute(args.stacktrace)
+ if r8_source_file:
+ map_path = get_map_from_r8_source_file_attribute(
+ args, r8_source_file, use_partition_map)
+ if map_path:
+ return (use_partition_map, map_path)
+ # If no other map file was found, use the local mapping file.
+ if args.r8jar:
+ return (False, args.r8jar + ".map")
+ return (False, utils.R8LIB_MAP)
+
+
+# Extract the R8 source file attribute from the stack trace if present.
+def get_r8_source_file_attribute(stacktrace):
r8_source_file = None
- for line in open(args.stacktrace, 'r'):
+ for line in open(stacktrace, 'r'):
start = line.rfind("(R8_")
if start > 0:
end = line.find(":", start)
@@ -101,41 +124,49 @@
print(' ' + content)
else:
r8_source_file = content
+ return r8_source_file
- if r8_source_file:
- (header, r8_version_or_hash, maphash) = r8_source_file.split('_')
- # If the command-line specified --exclude-deps then assume it is as previous
- # versions will not be marked as such in the source-file line.
- is_excldeps = args.exclude_deps
- excldeps_start = r8_version_or_hash.find('+excldeps')
- if (excldeps_start > 0):
- is_excldeps = True
- r8_version_or_hash = r8_version_or_hash[0:excldeps_start]
- if len(r8_version_or_hash) < 40:
- args.version = r8_version_or_hash
- else:
- args.commit_hash = r8_version_or_hash
- map_path = None
- if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(
- utils.R8LIB_MAP) == maphash:
- return utils.R8LIB_MAP
- try:
- map_path = utils.find_cloud_storage_file_from_options(
- 'r8lib' + ('-exclude-deps' if is_excldeps else '') + '.jar.map',
- args)
- except Exception as e:
- print(e)
- print('WARNING: Falling back to using local mapping file.')
+def get_map_from_r8_source_file_attribute(args, r8_source_file, use_partition_map):
+ (header, r8_version_or_hash, maphash) = r8_source_file.split('_')
+ # If the command-line specified --exclude-deps then assume it is as previous
+ # versions will not be marked as such in the source-file line.
+ is_excldeps = args.exclude_deps
+ excldeps_start = r8_version_or_hash.find('+excldeps')
+ if (excldeps_start > 0):
+ is_excldeps = True
+ r8_version_or_hash = r8_version_or_hash[0:excldeps_start]
+ if len(r8_version_or_hash) < 40:
+ args.version = r8_version_or_hash
+ else:
+ args.commit_hash = r8_version_or_hash
+ map_path = None
+ # First check local mapping file for map hash.
+ if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(
+ utils.R8LIB_MAP) == maphash:
+ return utils.R8LIB_MAP
+ try:
+ # Look for mapping file on GCS based on the version or commit hash
+ # found in the source file atttribute.
+ map_path = utils.find_cloud_storage_file_from_options(
+ 'r8lib' + ('-exclude-deps' if is_excldeps else '')
+ + ('.jar_map.zip' if use_partition_map else '.jar.map'),
+ args)
- if map_path and not args.disable_map_validation:
- check_maphash(map_path, maphash, args)
+ if map_path:
+ # Partition map is not validated. The mapping file header is
+ # in the METADATA blob together with some other imformation.
+ if not args.disable_map_validation and not use_partition_map:
+ check_maphash(map_path, maphash, args)
return map_path
+ except Exception as e:
+ print(e)
+ print('WARNING: Falling back to using local mapping file.')
# If no other map file was found, use the local mapping file.
if args.r8jar:
- return args.r8jar + ".map"
- return utils.R8LIB_MAP
+ return args.r8jar + ('_map.zip' if use_partition_map else ".map")
+ return utils.R8LIB_PARTITION_MAP if use_partition_map else utils.R8LIB_MAP
def check_maphash(mapping_path, maphash, args):
@@ -161,8 +192,16 @@
def main():
args = parse_arguments()
with utils.TempDir() as temp:
- map_path = get_map_file(args, temp)
+ # Get the stack trace to retrace.
+ if not args.stacktrace:
+ if not args.quiet:
+ print('Waiting for stack-trace input...')
+ args.stacktrace = os.path.join(temp, 'stacktrace.txt')
+ open(args.stacktrace, 'w').writelines(sys.stdin.readlines())
+
+ (is_partition_map, map_path) = get_map_file(args, temp)
return run(map_path,
+ is_partition_map,
args.stacktrace,
args.r8jar,
args.no_r8lib,
@@ -173,6 +212,7 @@
def run(map_path,
+ is_partition_map,
stacktrace,
r8jar,
no_r8lib,
@@ -191,8 +231,12 @@
r8jar = utils.R8_JAR if no_r8lib else utils.R8LIB_JAR
retrace_args += [
- '-cp', r8jar, 'com.android.tools.r8.retrace.Retrace', map_path
+ '-cp', r8jar, 'com.android.tools.r8.retrace.Retrace'
]
+ if is_partition_map:
+ retrace_args.extend(['--partition-map', map_path])
+ else:
+ retrace_args.append(map_path)
if regex:
retrace_args.append('--regex')