diff --git a/scripts/example_crashes.py b/scripts/example_crashes.py index 29f4c94ea..be72f8885 100755 --- a/scripts/example_crashes.py +++ b/scripts/example_crashes.py @@ -199,3 +199,32 @@ libmemunreachable = """ #00 pc 000076ae /system/lib/libcutils.so (set_process_name+45) #01 pc 000989d6 /system/lib/libandroid_runtime.so (android_os_Process_setArgV0(_JNIEnv*, _jobject*, _jstring*)+125) """ + +# This is a long crash in ASAN format, which does not pad frame numbers. This should be used +# in a test to ensure that the stack is not split into two (see stack_core's test_long_asan_crash). +long_asan_crash = """ +Build fingerprint: 'Android/aosp_arm/generic_arm:4.4.3.43.43.43/AOSP/enh06302258:eng/test-keys' +ABI: 'arm' + + #0 0x727d4dfdaf (/system/lib/libclang_rt.asan-arm-android.so+0x31daf) + + #1 0x727d4e00af (/system/lib/libclang_rt.asan-arm-android.so+0x320af) + + #2 0x72778db0cf (/data/lib/libc.so+0x740cf) + + #3 0x725688a66f (/does/not/matter/a.so+0x1066f) + + #4 0x72568a02af (/does/not/matter/a.so+0x262af) + + #5 0x725689e313 (/does/not/matter/a.so+0x24313) + + #6 0x72568a95eb (/does/not/matter/a.so+0x2f5eb) + + #7 0x725688de6f (/does/not/matter/a.so+0x13e6f) + + #8 0x72778ceeff (/does/not/matter/a.so+0x67eff) + + #9 0x7277884983 (/does/not/matter/a.so+0x1d983) + + #10 0x7277884983 (/does/not/matter/a.so+0x1d983) +""" diff --git a/scripts/stack_core.py b/scripts/stack_core.py index 6750667c0..f79280986 100755 --- a/scripts/stack_core.py +++ b/scripts/stack_core.py @@ -343,7 +343,7 @@ class TraceConverter: trace_line_dict = self.MatchTraceLine(line) if trace_line_dict is not None: ret = True - frame = trace_line_dict["frame"] + frame = int(trace_line_dict["frame"]) code_addr = trace_line_dict["offset"] area = trace_line_dict["dso"] so_offset = trace_line_dict["so_offset"] @@ -476,5 +476,26 @@ class LibmemunreachablePatternTests(unittest.TestCase): self.assertEquals(len(tc.trace_lines), 2) tc.PrintOutput(tc.trace_lines, tc.value_lines) +class LongASANStackTests(unittest.TestCase): + # Test that a long ASAN-style (non-padded frame numbers) stack trace is not split into two + # when the frame number becomes two digits. This happened before as the frame number was + # handled as a string and not converted to an integral. + def test_long_asan_crash(self): + tc = TraceConverter() + lines = example_crashes.long_asan_crash.splitlines() + symbol.SetAbi(lines) + tc.UpdateAbiRegexes() + # Test by making sure trace_line_count is monotonically non-decreasing. If the stack trace + # is split, a separator is printed and trace_lines is flushed. + trace_line_count = 0 + for line in lines: + tc.ProcessLine(line) + self.assertLessEqual(trace_line_count, len(tc.trace_lines)) + trace_line_count = len(tc.trace_lines) + # The split happened at transition of frame #9 -> #10. Make sure we have parsed (and stored) + # more than ten frames. + self.assertGreater(trace_line_count, 10) + tc.PrintOutput(tc.trace_lines, tc.value_lines) + if __name__ == '__main__': unittest.main()