def testClassifyCallStack(self): """Tests ``ClassifyCallStack`` method.""" callstack = CallStack(0, [ StackFrame(0, 'src/', 'func', 'comp1/a.cc', 'src/comp1/a.cc', [2]) ]) self.assertEqual(self.classifier.ClassifyCallStack(callstack), ['Comp1>Dummy']) callstack = CallStack(0, [ StackFrame(0, 'dummy/', 'no_func', 'comp2/a.cc', 'dummy/comp2.cc', [32]) ]) self.assertEqual(self.classifier.ClassifyCallStack(callstack), []) crash_stack = CallStack(0, frame_list=[ StackFrame(0, 'src/', 'func', 'comp1/a.cc', 'src/comp1/a.cc', [2]), StackFrame(1, 'src/', 'ff', 'comp1/a.cc', 'src/comp1/a.cc', [21]), StackFrame(2, 'src/', 'func2', 'comp2/b.cc', 'src/comp2/b.cc', [8]) ]) self.assertEqual(self.classifier.ClassifyCallStack(crash_stack), ['Comp1>Dummy', 'Comp2>Dummy'])
def testChromeCrashParserParseLineJavaCallstack(self): parser = ChromeCrashParser() deps = {'src/': Dependency('src/', 'https://repo', '1')} stacktrace_string = textwrap.dedent( """ (JAVA) CRASHED [EXC @ 0x508] #0 0x7fee in a.f0.c f0.java:177 #1 0x4b6e in org.chromium.chrome.browser.a.f1.d f1.java:227 #2 0x7ff9 in a.f2.e f2.java:87:1 """ ) stacktrace = parser.Parse(stacktrace_string, deps) stack = CallStack(0, language_type=LanguageType.JAVA, frame_list=[ StackFrame(0, '', 'a.f0.c', 'a/f0.java', 'a/f0.java', [177]), StackFrame( 1, 'src/', 'org.chromium.chrome.browser.a.f1.d', 'chrome/android/java/src/org/chromium/chrome/browser/a/f1.java', 'src/chrome/android/java/src/org/chromium/chrome/' 'browser/a/f1.java', [227]), StackFrame(2, '', 'a.f2.e', 'a/f2.java', 'a/f2.java', [87, 88])]) expected_stacktrace = Stacktrace([stack], stack) self._VerifyTwoStacktracesEqual(stacktrace, expected_stacktrace)
def testChromeCrashParserParseLineMultipleCallstacks(self): parser = ChromeCrashParser() deps = {'src/': Dependency('src/', 'https://repo', '1')} stacktrace_string = textwrap.dedent( """ CRASHED [EXC @ 0x66] #0 0x7fee in a::b::c(p* &d) src/f0.cc:177 #1 0x4b6e in a::b::d(a* c) src/f1.cc:227 CRASHED [EXC @ 0x508] #0 0x8fee in e::f::g(p* &d) src/f.cc:20:2 #1 0x1fae in h::i::j(p* &d) src/ff.cc:9:1 """ ) stacktrace = parser.Parse(stacktrace_string, deps) expected_callstack0 = CallStack(0, frame_list=[ StackFrame(0, 'src/', 'a::b::c(p* &d)', 'f0.cc', 'src/f0.cc', [177]), StackFrame(1, 'src/', 'a::b::d(a* c)', 'f1.cc', 'src/f1.cc', [227])]) expected_callstack1 = CallStack(0, frame_list=[ StackFrame( 0, 'src/', 'e::f::g(p* &d)', 'f.cc', 'src/f.cc', [20, 21, 22]), StackFrame( 1, 'src/', 'h::i::j(p* &d)', 'ff.cc', 'src/ff.cc', [9, 10])]) expected_stacktrace = Stacktrace([expected_callstack0, expected_callstack1], expected_callstack0) self._VerifyTwoStacktracesEqual(stacktrace, expected_stacktrace)
def testFilterInlineFunctions(self): """Tests that filtering all inline function frames.""" frame_list = [ StackFrame(0, 'src/', 'normal_func', 'f.cc', 'dummy/src/f.cc', [2]), StackFrame( 1, 'src/', 'inline_func', 'third_party/llvm-build/Release+Asserts/include/c++/v1/a', 'src/third_party/llvm-build/Release+Asserts/include/c++/v1/a', [1]), StackFrame( 2, 'src/', 'inline_func', 'linux/debian_wheezy_amd64-sysroot/usr/include/c++/4.6/bits/b', 'src/linux/debian_wheezy_amd64-sysroot/usr/include/c++/4.6/bits/b', [1]), StackFrame(3, 'src/', 'inline_func', 'eglibc-3GlaMS/eglibc-2.19/sysdeps/unix/c', 'src/eglibc-3GlaMS/eglibc-2.19/sysdeps/unix/c', [1]) ] expected_frame_list = frame_list[:1] self._VerifyTwoCallStacksEqual( callstack_filters.FilterInlineFunction()(CallStackBuffer( 0, frame_list=frame_list)), CallStackBuffer(0, frame_list=expected_frame_list))
def testMatchesStackFrame(self): """Tests that ``MatchesStackFrame`` matches frames.""" chromium_frame = StackFrame(0, 'src', 'func', 'f.cc', 'src/f.cc', [2]) self.assertTrue( self.chromium_project.MatchesStackFrame(chromium_frame)) self.assertFalse( self.android_project.MatchesStackFrame(chromium_frame)) android_frame1 = StackFrame(0, '', 'android.a', 'comp1.cc', 'src/comp1.cc', [2]) self.assertFalse( self.chromium_project.MatchesStackFrame(android_frame1)) self.assertTrue(self.android_project.MatchesStackFrame(android_frame1)) android_frame2 = StackFrame(0, '', 'func', 'comp2.cc', 'googleplex-android/src/comp2.cc', [32]) self.assertFalse( self.chromium_project.MatchesStackFrame(android_frame2)) self.assertTrue(self.android_project.MatchesStackFrame(android_frame2)) android_frame3 = StackFrame(0, 'googleplex-android/src', 'func', 'comp3.cc', 'googleplex-android/src/comp3.cc', [15]) self.assertFalse( self.chromium_project.MatchesStackFrame(android_frame3)) self.assertTrue(self.android_project.MatchesStackFrame(android_frame3))
def testClassifyCallStack(self): """Tests ``ClassifyCallStack`` method.""" callstack = CallStack( 0, [StackFrame(0, 'src', 'func', 'f.cc', 'src/f.cc', [2])]) self.assertEqual(self.classifier.ClassifyCallStack(callstack), 'chromium') callstack = CallStack( 0, [StackFrame(0, '', 'android.a', 'comp1.cc', 'src/comp1.cc', [2])]) self.assertEqual(self.classifier.ClassifyCallStack(callstack), 'android_os') callstack = CallStack(0, [ StackFrame(0, '', 'func', 'comp2.cc', 'googleplex-android/src/comp2.cc', [32]) ]) self.assertEqual(self.classifier.ClassifyCallStack(callstack), 'android_os') callstack = CallStack( 0, [StackFrame(0, '', 'func', 'comp2.cc', 'unknown/comp2.cc', [32])]) self.assertIsNone(self.classifier.ClassifyCallStack(callstack)) callstack = CallStack(0, [ StackFrame(0, '', 'android.a.b', 'f.java', 'unknown/f.java', [32]) ], language_type=LanguageType.JAVA) self.assertEqual(self.classifier.ClassifyCallStack(callstack), 'android_os')
def testDistanceBetweenTouchedFileAndFrameInfos(self): """Tests ``DistanceBetweenTouchedFileAndFrameInfos`` method.""" feature = min_distance.MinDistanceFeature(self._get_repository, _MAXIMUM) frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [7], repo_url='https://repo_url') frame2 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [17], repo_url='https://repo_url') touched_file = FileChangeInfo(ChangeType.MODIFY, 'file', 'file') blame = Blame('rev', 'src/') blame.AddRegions([Region(0, 10, 'rev', 'a1', 'e1', 't1'), Region(11, 20, 'dummy_rev', 'a2', 'e2', 't2')]) url_to_blame = {'rev/file': blame} def _MockGetBlame(path, revision): revision_path = '%s/%s' % (revision, path) return url_to_blame.get(revision_path) with mock.patch('libs.gitiles.gitiles_repository.GitilesRepository.' 'GetBlame') as mock_get_blame: mock_get_blame.side_effect = _MockGetBlame distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos( 'rev', touched_file, [FrameInfo(frame1, 0), FrameInfo(frame2, 0)], Dependency('src/', 'https://repo', 'rev')) self.assertEqual(distance_info, min_distance.Distance(0, frame1)) distance_info = feature.DistanceBetweenTouchedFileAndFrameInfos( 'wrong_rev', touched_file, [FrameInfo(frame1, 0), FrameInfo(frame2, 0)], Dependency('src/', 'https://repo', 'wrong_rev')) self.assertIsNone(distance_info)
def testClusterfuzzParserParseStacktrace(self): parser = ClusterfuzzParser() deps = {'src/': Dependency('src/', 'https://repo', '1')} stacktrace_string = textwrap.dedent(""" Blabla... ==1==ERROR: AddressSanitizer: stack-overflow on address 0x7ffec59ebec0 #0 0x7f5b944a37bb in a::aa(p* d) src/a.h:225 #1 0x7f5b9449a880 in b::bb(p* d) src/b.h:266:1 #2 0x7f5b9449a880 in c::cc(p* d) src/c.h:281 """) stacktrace = parser.Parse(stacktrace_string, deps, 'asan_job', SanitizerType.ADDRESS_SANITIZER) stack = CallStack(0, frame_list=[ StackFrame(0, 'src/', 'a::aa(p* d)', 'a.h', 'src/a.h', [225]), StackFrame(1, 'src/', 'b::bb(p* d)', 'b.h', 'src/b.h', [266, 267]), StackFrame(2, 'src/', 'c::cc(p* d)', 'c.h', 'src/c.h', [281]) ]) expected_stacktrace = Stacktrace([stack], stack) self._VerifyTwoStacktracesEqual(stacktrace, expected_stacktrace)
def testUpdateInvetedIndexHandlerWithStacktraces(self): """Tests ``UpdateInvertedIndex`` handler when there are stacktraces.""" crash_analysis = FracasCrashAnalysis.Create('sig1') crash_analysis.identifiers = {'signature': 'sig1'} crash_analysis.requested_time = datetime.utcnow() - timedelta(hours=1) frames = [ StackFrame(0, 'src/', 'fun1', 'f1.cc', 'src/f1.cc', [2, 3], 'http://repo'), StackFrame(0, 'src/', 'fun2', 'f2.cc', 'xx/src/f2.cc', [8, 10], 'http://repo'), StackFrame(0, 'src/', 'fun3', 'f3.cc', 'y/src/f3.cc', [20, 30], 'http://repo') ] callstack = CallStack(0, frames) crash_analysis.stacktrace = Stacktrace([callstack], callstack) crash_analysis.put() response = self.test_app.get('/process/update-inverted-index', headers={'X-AppEngine-Cron': 'true'}) self.assertEqual(response.status_int, 200) self.assertEqual(ChromeCrashInvertedIndex.GetRoot().n_of_doc, 1) self.assertEqual(ChromeCrashInvertedIndex.Get('src/f1.cc').n_of_doc, 1) self.assertEqual(ChromeCrashInvertedIndex.Get('src/f2.cc').n_of_doc, 1) self.assertEqual(ChromeCrashInvertedIndex.Get('src/f3.cc').n_of_doc, 1)
def testClassifyStackFrameEmptyFrame(self): """Tests that ``ClassifyStackFrame`` returns None for empty frame.""" frame = StackFrame(0, None, 'func', 'comp1/a.cc', 'src/comp1/a.cc', [2]) self.assertIsNone(self.classifier.ClassifyStackFrame(frame)) frame = StackFrame(0, 'src/', 'func', None, 'src/comp1/a.cc', [2]) self.assertIsNone(self.classifier.ClassifyStackFrame(frame))
def setUp(self): super(CallStackBufferTest, self).setUp() self.stack_buffer = CallStackBuffer( 0, frame_list=[ StackFrame(0, 'repo/path1', 'func1', 'a/c/f1.cc', 'a/b/f1.cc', [1, 2], 'https://repo1'), StackFrame(1, 'repo/path2', 'func2', 'a/c/f2.cc', 'a/b/f2.cc', [11, 12, 13], 'https://repo2') ])
def testStackFrameToString(self): self.assertEqual( StackFrame(0, 'src/', 'func', 'f.cc', 'src/f.cc', []).ToString(), '#0 in func @ f.cc') self.assertEqual( StackFrame(0, 'src/', 'func', 'f.cc', 'src/f.cc', [1]).ToString(), '#0 in func @ f.cc:1') self.assertEqual( StackFrame(0, 'src/', 'func', 'f.cc', 'src/f.cc', [1, 2]).ToString(), '#0 in func @ f.cc:1:1')
def testAddFitleredStackWithNoFilters(self): """Tests that ``AddFilteredStack`` returns None if there is no filters.""" frame_list = [ StackFrame(0, 'src/', 'func', 'file0.cc', 'src/file0.cc', [32]), StackFrame(0, 'src/', 'func2', 'file0.cc', 'src/file0.cc', [32]) ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) stacktrace_buffer = StacktraceBuffer() stacktrace_buffer.AddFilteredStack(stack_buffer) self.assertEqual(len(stacktrace_buffer.stacks), 1)
def testParseStackFrameForFracasJavaStack(self): format_type = CallStackFormatType.DEFAULT language_type = LanguageType.JAVA frame = StackFrame.Parse(language_type, format_type, '#0 0xxx in android.app.func app.java:2450', {}) self._VerifyTwoStackFramesEqual( frame, StackFrame(0, '', 'android.app.func', 'android/app.java', 'android/app.java', [2450]))
def testDoNothingForNonV8APIBindingStack(self): """Tests that filter does nothing for non v8 api binding stack.""" frame_list = [ StackFrame(0, 'src/v8', 'func', 'f.cc', 'f.cc', [1]), StackFrame(2, 'src', 'func', 'a.cc', 'a.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) self._VerifyTwoCallStacksEqual( callstack_filters.FilterV8FramesForV8APIBindingCode()( stack_buffer), stack_buffer)
def testDoNothingIfTopNFramesFieldIsEmpty(self): """Tests that if top_n_frames is None, filter does nothing.""" frame_list = [ StackFrame(0, 'src/', 'normal_func', 'f.cc', 'dummy/src/f.cc', [2]), StackFrame(1, 'src/', 'func', 'a.cc', 'a.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) self._VerifyTwoCallStacksEqual( callstack_filters.RemoveTopNFrames()(stack_buffer), stack_buffer)
def testDoNothingIfNoBlinkBindingGeneratedCode(self): """Tests that filter does nothing if no blink binding generated code.""" frame_list = [ StackFrame(0, 'src/v8', 'func', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func', 'b.cc', 'b.cc', [2, 3]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) self._VerifyTwoCallStacksEqual( callstack_filters.FilterFramesAfterBlinkGeneratedCode()( stack_buffer), stack_buffer)
def testFilterV8FramesForNullPointerDereference(self): """Tests that filtering all v8 frames for null pointer dereference stack.""" frame_list = [ StackFrame(0, 'src/v8', 'func', 'src/api.h', 'src/api.h', [1]), StackFrame(2, 'src', 'func', 'a.cc', 'a.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) expected_stack_buffer = CallStackBuffer(0, frame_list=frame_list[1:]) self._VerifyTwoCallStacksEqual( callstack_filters.FilterV8FramesForV8APIBindingCode('0x0000')( stack_buffer), expected_stack_buffer)
def testDoNothingIfSignatueIsEmpty(self): """Tests filter does nothing if the signature is empty.""" frame_list = [ StackFrame(0, 'src', 'func0', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func1', 'b.cc', 'b.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) expected_stack_buffer = CallStackBuffer(0, frame_list=frame_list) self._VerifyTwoCallStacksEqual( callstack_filters.FilterFramesBeforeAndInBetweenSignatureParts( None)(stack_buffer), expected_stack_buffer)
def testDoNothingIfNoMatchBetweenFramesAndSignature(self): """Tests filter does nothing if frames and signature do not match.""" frame_list = [ StackFrame(0, 'src', 'func0', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func1', 'b.cc', 'b.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) expected_stack_buffer = CallStackBuffer(0, frame_list=frame_list) self._VerifyTwoCallStacksEqual( callstack_filters.FilterFramesBeforeAndInBetweenSignatureParts( 'signature')(stack_buffer), expected_stack_buffer)
def testParseStackFrameForJavaCallstackFormat(self): language_type = None format_type = CallStackFormatType.JAVA self.assertIsNone( StackFrame.Parse(language_type, format_type, 'dummy line', {})) deps = {'org/': Dependency('org/', 'https://repo', '1')} frame = StackFrame.Parse(language_type, format_type, ' at org.a.b(a.java:609)', deps) self._VerifyTwoStackFramesEqual( frame, StackFrame(0, 'org/', 'org.a.b', 'a.java', 'org/a.java', [609]))
def testDoNotFilterNonJavaCallStack(self): """Tests do not filtering non java callstack.""" frame_list = [ StackFrame(0, 'src', 'func0', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func1', 'b.cc', 'b.cc', [1]), ] stack_buffer = CallStackBuffer(frame_list=frame_list, language_type=LanguageType.CPP) expected_stack_buffer = copy.deepcopy(stack_buffer) self._VerifyTwoCallStacksEqual( callstack_filters.FilterJavaCallStackIfNotCrashStack()( stack_buffer), expected_stack_buffer)
def testDoNothingIfV8InTopFrames(self): """Tests that filter does nothing if there is v8 frame in top frames.""" frame_list = [ StackFrame(0, 'src/v8', 'func', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func', 'b.cc', 'b.cc', [1]), StackFrame(2, 'src', 'func', 'c.cc', 'c.cc', [2, 3]), StackFrame(3, 'src/v8', 'func', 'd.cc', 'd.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) self._VerifyTwoCallStacksEqual( callstack_filters.FilterV8FramesIfV8NotInTopFrames(2)( stack_buffer), stack_buffer)
def testRemoveTopNFrames(self): """Tests removing the top n frames of a callstack.""" frame_list = [ StackFrame(0, 'src/', 'normal_func', 'f.cc', 'dummy/src/f.cc', [2]), StackFrame(1, 'src/', 'func', 'a.cc', 'a.cc', [1]), ] top_n = 1 self._VerifyTwoCallStacksEqual( callstack_filters.RemoveTopNFrames(top_n)(CallStackBuffer( 0, frame_list=frame_list)), CallStackBuffer(0, frame_list=frame_list[top_n:]))
def testParseStackFrameForSyzyasanCallstackFormat(self): language_type = None format_type = CallStackFormatType.SYZYASAN self.assertIsNone( StackFrame.Parse(language_type, format_type, 'dummy line', {})) deps = {'src/content': Dependency('src/content', 'https://repo', '1')} frame = StackFrame.Parse(language_type, format_type, 'c::p::n [src/content/e.cc @ 165]', deps) self._VerifyTwoStackFramesEqual( frame, StackFrame(0, 'src/content', 'c::p::n', 'e.cc', 'src/content/e.cc', [165]))
def testDoNotFilterJavaCallStackIfCrashStack(self): """Tests do not filtering the java callstack if it's the crash stack.""" frame_list = [ StackFrame(0, 'android', 'func0', 'a.java', 'a.java', [1]), StackFrame(1, 'android', 'func1', 'b.java', 'b.java', [1]), ] stack_buffer = CallStackBuffer(frame_list=frame_list, language_type=LanguageType.JAVA, metadata={'is_signature_stack': True}) expected_stack_buffer = copy.deepcopy(stack_buffer) self._VerifyTwoCallStacksEqual( callstack_filters.FilterJavaCallStackIfNotCrashStack()( stack_buffer), expected_stack_buffer)
def testDoNothingForNonV8GeneratedJITCrash(self): """Tests that filter does nothing for non v8 generated JIT crash.""" frame_list = [ StackFrame(0, 'src/v8', 'func', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func', 'b.cc', 'b.cc', [2, 3]), ] stack_buffer = CallStackBuffer( 0, frame_list=frame_list, metadata={'top_frame_has_no_symbols': True}) self._VerifyTwoCallStacksEqual( callstack_filters.KeepV8FramesIfV8GeneratedJITCrash()( stack_buffer), stack_buffer)
def testStacktraceLen(self): """Tests ``len`` for ``Stacktrace`` object.""" frame_list1 = [ StackFrame(0, 'src/', 'func', 'file0.cc', 'src/file0.cc', [32]) ] frame_list2 = [ StackFrame(0, 'src/', 'func2', 'file0.cc', 'src/file0.cc', [32]) ] stack1 = CallStack(0, frame_list1, None, None) stack2 = CallStack(1, frame_list2, None, None) stacktrace = Stacktrace((stack1, stack2), stack1) self.assertEqual(len(stacktrace), 2)
def testFilterAllFramesBeforeTheFirstMatchedSignaturePart(self): """Tests filtering frames before the first matched signature part.""" frame_list = [ StackFrame(0, 'src/v8', 'func0', 'a.cc', 'a.cc', [1]), StackFrame(1, 'src', 'func1', 'b.cc', 'b.cc', [1]), StackFrame(2, 'src', 'func2', 'c.cc', 'c.cc', [2, 3]), StackFrame(3, 'src/v8', 'func3', 'd.cc', 'd.cc', [1]), ] stack_buffer = CallStackBuffer(0, frame_list=frame_list) expected_stack_buffer = CallStackBuffer(0, frame_list=frame_list[2:]) self._VerifyTwoCallStacksEqual( callstack_filters.FilterFramesBeforeAndInBetweenSignatureParts( 'dummy\nfunc2\nfunc3\n')(stack_buffer), expected_stack_buffer)
def testFilterJavaCallStackIfNotCrashStack(self): """Tests filtering the java callstack if it's not the crash stack.""" frame_list = [ StackFrame(0, 'android', 'func0', 'a.java', 'a.java', [1]), StackFrame(1, 'android', 'func1', 'b.java', 'b.java', [1]), ] stack_buffer = CallStackBuffer(frame_list=frame_list, language_type=LanguageType.JAVA) expected_stack_buffer = CallStackBuffer( frame_list=[], language_type=LanguageType.JAVA) self._VerifyTwoCallStacksEqual( callstack_filters.FilterJavaCallStackIfNotCrashStack()( stack_buffer), expected_stack_buffer)