From ad7d5fb378eca464dbf33c5267c5e91b735bb16c Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Mon, 9 Jul 2018 14:48:15 -0700 Subject: [PATCH] Detect if num field is valid on v1.0 version. In Android P, the version field did not get incremented properly in all places. So if a file with a v1.0 version is found, do a further check to verify if the num field is really valid. Test: Verified that a file with v1.0 gets checked and the valid num field Test: is set correctly. Test: Verified that a file with v1.1 automatically gets num field set to Test: valid. Change-Id: I7f828294c833e334cad76a866bbaa1d78ac02cfb Merged-In: I7f828294c833e334cad76a866bbaa1d78ac02cfb (cherry picked from commit b558fe4d53cf641f68c2086b3847690c56e0f9cf) --- scripts/native_heapdump_viewer.py | 43 ++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/scripts/native_heapdump_viewer.py b/scripts/native_heapdump_viewer.py index 32b99db3c..b74b1b52c 100755 --- a/scripts/native_heapdump_viewer.py +++ b/scripts/native_heapdump_viewer.py @@ -117,11 +117,52 @@ def GetVersion(native_heap): return m.group('version') return None +def NumFieldValid(native_heap): + """Determine if the num field is valid. + + Malloc debug for N incorrectly set the num field to the number of + backtraces instead of the number of allocations with the same size and + backtrace. Read the file and if at least three lines all have the field + set to the number of backtraces values, then consider this generated by + the buggy malloc debug and indicate the num field is not valid. + + Returns: + True if the num field is valid. + False if the num field is not valid and should be ignored. + """ + + re_backtrace = re.compile("Backtrace\s+size:\s+(?P\d+)") + + re_line = re.compile("z\s+(?P\d+)\s+sz\s+(?P\d+)\s+num\s+(?P\d+)") + matched = 0 + backtrace_size = 0 + for line in open(native_heap, "r"): + if backtrace_size == 0: + m = re_backtrace.match(line) + if m: + backtrace_size = int(m.group('backtrace_size')) + parts = line.split() + if len(parts) > 7 and parts[0] == "z" and parts[2] == "sz": + m = re_line.match(line) + if m: + num_allocations = int(m.group('num_allocations')) + if num_allocations == backtrace_size: + # At least three lines must match this pattern before + # considering this the old buggy version of malloc debug. + matched += 1 + if matched == 3: + return False + else: + return True + return matched == 0 + version = GetVersion(native_heap) if not version or version == "v1.0": # Version v1.0 was produced by a buggy version of malloc debug where the # num field was set incorrectly. - num_field_valid = False + # Unfortunately, Android P produced a v1.0 version that does set the + # num field. Do one more check to see if this is the broken version. + num_field_valid = NumFieldValid(native_heap) else: num_field_valid = True