def Parse(self, stacktrace_string, deps, signature=None, top_n_frames=None): """Parse fracas stacktrace string into Stacktrace instance.""" # Filters to filter callstack buffers. filters = [ callstack_filters.FilterInlineFunction(), callstack_filters.KeepTopNFrames(top_n_frames or DEFAULT_TOP_N_FRAMES) ] stacktrace_buffer = StacktraceBuffer(signature=signature, filters=filters) stack_detector = callstack_detectors.ChromeCrashStackDetector() # Initial background callstack which is not to be added into Stacktrace. stack_buffer = CallStackBuffer() for line in stacktrace_string.splitlines(): start_of_callstack = stack_detector(line) if start_of_callstack: stacktrace_buffer.AddFilteredStack(stack_buffer) stack_buffer = CallStackBuffer.FromStartOfCallStack( start_of_callstack) else: frame = StackFrame.Parse(stack_buffer.language_type, stack_buffer.format_type, line, deps, len(stack_buffer.frames)) if frame is not None: stack_buffer.frames.append(frame) # Add the last stack to stacktrace. stacktrace_buffer.AddFilteredStack(stack_buffer) return stacktrace_buffer.ToStacktrace()
def Parse( self, stacktrace_string, deps, job_type, # pylint: disable=W0221 sanitizer, signature=None, top_n_frames=None, crash_address=None): """Parse clusterfuzz stacktrace string into Stacktrace instance.""" filters = [ FilterJavaJreSdkFrames(), KeepV8FramesIfV8GeneratedJITCrash(), FilterV8FramesForV8APIBindingCode(crash_address), FilterFramesAfterBlinkGeneratedCode(), FilterV8FramesIfV8NotInTopFrames(), KeepTopNFrames(top_n_frames or DEFAULT_TOP_N_FRAMES) ] stacktrace_buffer = StacktraceBuffer(signature=signature, filters=filters) stack_detector = GetCallStackDetector(job_type, sanitizer) if stack_detector is None: logging.error( 'Cannot find CallStackDetector for crash %s (job type: %s)', signature or '', job_type) return None # Initial background callstack which is not to be added into Stacktrace. stack_buffer = CallStackBuffer() # Reset both stacktrace and callstack flags. self.flag_manager.ResetAllFlags() for line in stacktrace_string.splitlines(): # Note, some flags like is_first_stack may be changed inside of stack # detector. start_of_callstack = stack_detector(line, flags=self.flag_manager) if start_of_callstack: stacktrace_buffer.AddFilteredStack( self.UpdateMetadataWithFlags(stack_buffer)) # Create new stack and reset callstack scope flags. stack_buffer = CallStackBuffer.FromStartOfCallStack( start_of_callstack) self.flag_manager.ResetGroupFlags(CALLSTACK_FLAG_GROUP) else: frame = StackFrame.Parse(stack_buffer.language_type, stack_buffer.format_type, line, deps, len(stack_buffer.frames)) if frame is not None: stack_buffer.frames.append(frame) # Turn on flags if condition met. self.flag_manager.ConditionallyTurnOnFlags(line) # Add the last stack to stacktrace. stacktrace_buffer.AddFilteredStack( self.UpdateMetadataWithFlags(stack_buffer)) return stacktrace_buffer.ToStacktrace()
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 Parse(self, stacks, subtree_root_depth, deps): """Parse the list of stacks provided by UMA into a ``Stacktrace`` object. Args: stacks (list): List of dicts representing stacks, e.g.: [ { 'frames': [ { 'difference': 0.0018545067156028328, 'log_change_factor': -8.1878, 'responsible': false, 'filename': 'chrome/app/chrome_exe_main_win.cc', 'function_name': 'wWinMain', 'function_start_line': 484, 'callee_lines': [{'line': 490, 'sample_fraction': 0.9}, {'line': 511, 'sample_fraction': 0.1}] }, ... ] }, ... ] subtree_root_depth (int): Depth of the subtree root. Frames above this depth will be filtered out so that the ``Stacktrace`` object consists only of the subtree. deps (dict): Map dependency path to its corresponding Dependency. Returns: ``Stacktrace`` object or ``None`` if the stacktrace is empty. """ # TODO(wittman): Change the filtering logic to use the ``responsible`` field # after old data has been re-generated if _IncludeFrameAboveRoot(stacks, subtree_root_depth): filter_depth = subtree_root_depth - 1 else: filter_depth = subtree_root_depth filters = [callstack_filters.RemoveTopNFrames(filter_depth)] stacktrace_buffer = StacktraceBuffer(filters=filters) for stack in stacks: # TODO(cweakliam) determine how best to calculate priority for a callstack # (or if I even need to) callstack_buffer = CallStackBuffer(priority=0) for index, frame in enumerate(stack['frames']): frame_object, language_type = ProfilerStackFrame.Parse( frame, index, deps) callstack_buffer.frames.append(frame_object) if callstack_buffer: callstack_buffer.language_type = language_type stacktrace_buffer.AddFilteredStack(callstack_buffer) return stacktrace_buffer.ToStacktrace()
def testFilterAllFrames(self): """Tests that ``AddFilteredStack`` filters all frames and resturns None.""" 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) def _MockFilterAllFrames(stack_buffer): stack_buffer.frames = None return stack_buffer stacktrace_buffer = StacktraceBuffer(filters=[_MockFilterAllFrames]) stacktrace_buffer.AddFilteredStack(stack_buffer) self.assertEqual(len(stacktrace_buffer.stacks), 0)
def testFilterSomeFrames(self): """Tests that ``AddFilteredStack`` filters some frames.""" 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) def _MockKeepFirstFrame(stack): stack.frames = stack.frames[:1] return stack stacktrace_buffer = StacktraceBuffer(filters=[_MockKeepFirstFrame]) stacktrace_buffer.AddFilteredStack(stack_buffer) self._VerifyTwoCallStacksEqual( stacktrace_buffer.stacks[0], CallStackBuffer(stack_buffer.priority, frame_list=frame_list[:1]))
def testStacktraceBufferWithoutSignature(self): """Tests using least priority stack as crash_stack without signature.""" 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 = CallStackBuffer(0, frame_list=frame_list1) stack2 = CallStackBuffer(1, frame_list=frame_list2) stacktrace = StacktraceBuffer([stack1, stack2]).ToStacktrace() self._VerifyTwoCallStacksEqual(stacktrace.crash_stack, stack1.ToCallStack())
def testSettingStackWithIsSignatureStackMetaDataAsCrashStack(self): """Tests using stack with signature as crash_stack with signature.""" frame_list1 = [ StackFrame(0, 'src', 'func', 'file0.cc', 'src/file0.cc', [32]) ] frame_list2 = [ StackFrame(0, 'src', 'signature_func2', 'f.cc', 'src/f.cc', [32]) ] stack1 = CallStackBuffer(0, frame_list=frame_list1, metadata={'is_signature_stack': True}) stack2 = CallStackBuffer(1, frame_list=frame_list2) stacktrace = StacktraceBuffer([stack1, stack2]).ToStacktrace() self._VerifyTwoCallStacksEqual(stacktrace.crash_stack, stack1.ToCallStack())
def testEmptyStacktraceBufferToStacktrace(self): """Tests that ``ToStacktrace`` returns None for empty stacktrace buffer.""" self.assertIsNone(StacktraceBuffer([]).ToStacktrace())
def testFilterEmptyStackBuffer(self): """Tests that ``AddFilteredStack`` returns None for empty stack buffer.""" stack_buffer = CallStackBuffer(frame_list=[]) stacktrace_buffer = StacktraceBuffer(filters=[self._DummyFilter]) stacktrace_buffer.AddFilteredStack(stack_buffer) self.assertEqual(len(stacktrace_buffer.stacks), 0)
def testFilterInfinityPriorityStackBuffer(self): """Tests that ``AddFilteredStack`` returns None for inf priority stack.""" stack_buffer = CallStackBuffer(priority=float('inf')) stacktrace_buffer = StacktraceBuffer(filters=[self._DummyFilter]) stacktrace_buffer.AddFilteredStack(stack_buffer) self.assertEqual(len(stacktrace_buffer.stacks), 0)