Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import logging | |
| 6 import re | |
| 7 | |
| 8 from crash import callstack_detectors | |
| 9 from crash.callstack_filters import FilterFramesAfterBlinkGeneratedCode | |
| 10 from crash.callstack_filters import FilterJavaJreSdkFrames | |
| 11 from crash.callstack_filters import FilterV8FramesForV8APIBindingCode | |
| 12 from crash.callstack_filters import FilterV8FramesIfV8NotInTopFrames | |
| 13 from crash.callstack_filters import KeepV8FramesIfV8GeneratedJITCrash | |
| 14 from crash.callstack_filters import KeepTopNFrames | |
| 15 from crash.flag_manager import ParsingFlag | |
| 16 from crash.flag_manager import FlagManager | |
| 17 from crash.stacktrace import CallStackBuffer | |
| 18 from crash.stacktrace import StackFrame | |
| 19 from crash.stacktrace import StacktraceBuffer | |
| 20 from crash.stacktrace_parser import StacktraceParser | |
| 21 from crash.type_enums import CallStackFormatType | |
| 22 from crash.type_enums import LanguageType | |
| 23 from crash.type_enums import SanitizerType | |
| 24 | |
| 25 TOP_FRAME_HAS_NO_SYMBOLS_REGEX = re.compile( | |
| 26 r'.*#0 0x[0-9a-f]+ \(<unknown module>\).*') | |
| 27 SUMMARY_MARKER = 'SUMMARY:' | |
| 28 JAVA_FATAL_EXCEPTION_REGEX = re.compile('.*FATAL EXCEPTION.*:') | |
| 29 | |
| 30 ANDROID_JOB_TYPE_MARKER = 'android' | |
| 31 DEFAULT_TOP_N_FRAMES = 7 | |
| 32 | |
| 33 CALLSTACK_FLAG_GROUP = 'callstack_flags' | |
| 34 STACKTRACE_FLAG_GROUP = 'stacktrace_flags' | |
| 35 | |
| 36 SANITIZER_TO_CALLSTACK_DETECTOR_CLASS = { | |
| 37 SanitizerType.SYZYASAN: callstack_detectors.SyzyasanDetector, | |
| 38 SanitizerType.THREAD_SANITIZER: callstack_detectors.TsanDetector, | |
| 39 SanitizerType.UBSAN: callstack_detectors.UbsanDetector, | |
| 40 SanitizerType.MEMORY_SANITIZER: callstack_detectors.MsanDetector, | |
| 41 SanitizerType.ADDRESS_SANITIZER: callstack_detectors.AsanDetector | |
| 42 } | |
| 43 | |
| 44 | |
| 45 def GetCallStackDetector(job_type, sanitizer): | |
| 46 """Returns a ``CallStackDetector`` for particular sanitizer and job type.""" | |
| 47 | |
| 48 if ANDROID_JOB_TYPE_MARKER in job_type: | |
| 49 return callstack_detectors.AndroidJobDetector() | |
| 50 | |
| 51 try: | |
| 52 return SANITIZER_TO_CALLSTACK_DETECTOR_CLASS[sanitizer]() | |
| 53 except KeyError: | |
| 54 return None | |
| 55 | |
| 56 | |
| 57 class ClusterfuzzParser(StacktraceParser): | |
| 58 | |
| 59 def __init__(self): | |
| 60 self.flag_manager = FlagManager() | |
| 61 self.flag_manager.Register(STACKTRACE_FLAG_GROUP, ParsingFlag( | |
| 62 'java_main_stack', lambda line: # pylint: disable=W0108 | |
| 63 JAVA_FATAL_EXCEPTION_REGEX.match(line))) | |
| 64 self.flag_manager.Register(STACKTRACE_FLAG_GROUP, ParsingFlag( | |
| 65 'after_summary_line', lambda line: # pylint: disable=W0108 | |
| 66 SUMMARY_MARKER in line)) | |
| 67 # This flag is True at the very beginning and will never be changed once it | |
| 68 # is set to False. | |
| 69 self.flag_manager.Register(STACKTRACE_FLAG_GROUP, ParsingFlag( | |
| 70 'is_first_stack', | |
| 71 lambda line: False, value=True)) # pylint: disable=W0108 | |
| 72 self.flag_manager.Register(CALLSTACK_FLAG_GROUP, ParsingFlag( | |
| 73 'top_frame_has_no_symbol', lambda line: # pylint: disable=W0108 | |
| 74 TOP_FRAME_HAS_NO_SYMBOLS_REGEX.match(line))) | |
| 75 | |
| 76 def UpdateMetadataWithFlags(self, stack_buffer): | |
| 77 """ Updates metadata with callstack flags. Returns updated stack buffer.""" | |
|
wrengr
2016/12/28 23:47:52
extraneous space at start of docstring
Sharu Jiang
2016/12/29 18:29:21
Done.
| |
| 78 for flag in self.flag_manager.GetGroupFlags(CALLSTACK_FLAG_GROUP): | |
| 79 stack_buffer.metadata[flag.name] = flag.value | |
| 80 return stack_buffer | |
| 81 | |
| 82 def Parse(self, stacktrace_string, deps, job_type, # pylint: disable=W0221 | |
| 83 signature=None, top_n_frames=None, | |
| 84 crash_address=None): | |
| 85 """Parse clusterfuzz stacktrace string into Stacktrace instance.""" | |
| 86 filters = [FilterJavaJreSdkFrames(), | |
| 87 KeepV8FramesIfV8GeneratedJITCrash(), | |
| 88 FilterV8FramesForV8APIBindingCode(crash_address), | |
| 89 FilterFramesAfterBlinkGeneratedCode(), | |
| 90 FilterV8FramesIfV8NotInTopFrames(), | |
| 91 KeepTopNFrames(top_n_frames or DEFAULT_TOP_N_FRAMES)] | |
| 92 sanitizer = SanitizerType.GetSanitizerType(job_type, stacktrace_string) | |
| 93 stacktrace_buffer = StacktraceBuffer(signature=signature, filters=filters) | |
| 94 | |
| 95 stack_detector = GetCallStackDetector(job_type, sanitizer) | |
| 96 if stack_detector is None: | |
| 97 logging.error('Cannot find CallStackDetector for crash %s (job type: %s)', | |
| 98 signature or '', job_type) | |
| 99 return None | |
| 100 | |
| 101 # Initial background callstack which is not to be added into Stacktrace. | |
| 102 stack_buffer = CallStackBuffer() | |
| 103 # Reset both stacktrace and callstack flags. | |
| 104 self.flag_manager.ResetAllFlags() | |
| 105 for line in stacktrace_string.splitlines(): | |
| 106 # Note, some flags like is_first_stack may be changed inside of stack | |
| 107 # detector. | |
| 108 is_new_callstack, priority, format_type, language_type, metadata = ( | |
| 109 stack_detector.IsStartOfNewCallStack(line, flags=self.flag_manager)) | |
| 110 | |
| 111 if is_new_callstack: | |
| 112 stacktrace_buffer.AddFilteredStack( | |
| 113 self.UpdateMetadataWithFlags(stack_buffer)) | |
| 114 | |
| 115 # Create new stack and reset callstack scope flags. | |
| 116 stack_buffer = CallStackBuffer(priority=priority, | |
| 117 format_type=format_type, | |
| 118 language_type=language_type, | |
| 119 metadata=metadata) | |
| 120 self.flag_manager.ResetGroupFlags(CALLSTACK_FLAG_GROUP) | |
| 121 else: | |
| 122 frame = StackFrame.Parse(stack_buffer.language_type, | |
| 123 stack_buffer.format_type, line, deps, | |
| 124 len(stack_buffer.frames)) | |
| 125 if frame is not None: | |
| 126 stack_buffer.frames.append(frame) | |
| 127 # Turn on flags if condition met. | |
| 128 self.flag_manager.ConditionallyTurnOnFlags(line) | |
| 129 | |
| 130 # Add the last stack to stacktrace. | |
| 131 stacktrace_buffer.AddFilteredStack( | |
| 132 self.UpdateMetadataWithFlags(stack_buffer)) | |
| 133 return stacktrace_buffer.ToStacktrace() | |
| OLD | NEW |