Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: appengine/findit/crash/callstack_detectors.py

Issue 2593593003: [Predator] Add Clusterfuzz stacktrace parser. (Closed)
Patch Set: fix nits. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 re
6
7 from crash.type_enums import CallStackFormatType
8 from crash.type_enums import LanguageType
9 from crash.type_enums import SanitizerType
10
11
12 class CallStackDetector(object):
13 """Detector to detect the start of a CallStack."""
wrengr 2016/12/22 23:28:36 "detector to detect" is awkward. Try something lik
Sharu Jiang 2016/12/28 20:16:46 good point. Done.
14
15 def IsStartOfNewCallStack(self, line, flags=None):
16 """Determines whether a line is the start of a new callstack or not.
17
18 Args:
19 line (str): The line to be checked whether it is a start of new callstack
wrengr 2016/12/22 23:28:36 I'd drop the "whether..." part. If retained, then
Sharu Jiang 2016/12/28 20:16:46 Done.
20 or not.
21 flags (FlagManager): flag manager to manage flags needed to determine
wrengr 2016/12/22 23:28:35 "flag manager to manage flags" is awkward. Just sa
Sharu Jiang 2016/12/28 20:16:46 Done.
22 whether a line is the start of a new callstack.
23
24 Returns:
25 A tuple -
26 (is_new_callstack, priority, format_type, language_type, metadata)
wrengr 2016/12/22 23:28:36 It'd help clarify things to break this out as a na
Sharu Jiang 2016/12/28 20:16:46 Added a todo.
27 is_new_callstack (bool): Boolean indicating whether this is the start of
28 a new callstack.
29 priority (int): Priority of a callstack.
30 format_type (CallStackFormatType): Format type of new callstack.
wrengr 2016/12/22 23:28:35 -> "the format of the new callstack (or None if th
Sharu Jiang 2016/12/28 20:16:46 Done.
31 language_type (LanguageType): Language type of new callstack.
wrengr 2016/12/22 23:28:35 -> "the language of the new callstack (or None if
Sharu Jiang 2016/12/28 20:16:46 Done.
32 metadata (dict): Dict of metadata of new callstack,
wrengr 2016/12/22 23:28:35 "metadata of" -> "metadata for the"
Sharu Jiang 2016/12/28 20:16:46 Done.
33 e.g. pid, top_frame_has_no_symbols.
34 """
35 raise NotImplementedError()
36
37
38 class AndroidJobDetector(CallStackDetector):
39 """Detects the start of an android job callstack."""
40 JAVA_LANG_CALLSTACK_START_PATTERN = r'^java\.[A-Za-z0-9$._]+'
41 JAVA_ORG_GHROMIUM_CALLSTACK_START_PATTERN = r'^org\.chromium\.[A-Za-z0-9$._]+'
42 JAVA_CAUSED_BY_CALLSTACK_START_PATTERN = r'^Caused by:'
43 JAVA_ANDROID_CALLSTACK_START_PATTERN = (
44 r'^(com\.google\.)?android\.[A-Za-z0-9$._]+')
45
46 JAVA_CALLSTACK_START_REGEX = re.compile(
47 '|'.join([JAVA_LANG_CALLSTACK_START_PATTERN,
48 JAVA_ORG_GHROMIUM_CALLSTACK_START_PATTERN,
49 JAVA_CAUSED_BY_CALLSTACK_START_PATTERN,
50 JAVA_ANDROID_CALLSTACK_START_PATTERN]))
51
52 def IsStartOfNewCallStack(self, line, flags=None):
53 if AndroidJobDetector.JAVA_CALLSTACK_START_REGEX.match(line):
54 # Only assign the highest priority to fatal exception stack or segv
55 # stack.
56 if flags and flags.Get('java_main_stack_flag'):
57 flags.Set('java_main_stack_flag', False)
58 return True, 0, CallStackFormatType.JAVA, LanguageType.JAVA, {}
59
60 return True, 1, CallStackFormatType.JAVA, LanguageType.JAVA, {}
61
62 return False, None, None, None, None
63
64
65 class SyzyasanDetector(CallStackDetector):
66 """Detects the start of a syzyasn callstack."""
67 SYZYASAN_CRASH_CALLSTACK_START_REGEX = re.compile(r'^Crash stack:$')
68 SYZYASAN_NON_CRASH_CALLSTACK_START_REGEX = re.compile(r'^(?!Crash).* stack:$')
69
70 def IsStartOfNewCallStack(self, line, flags=None):
71 # In syzyasan build, new stack starts with 'crash stack:',
72 # 'freed stack:', etc.
73 if SyzyasanDetector.SYZYASAN_CRASH_CALLSTACK_START_REGEX.match(line):
74 return True, 0, CallStackFormatType.SYZYASAN, LanguageType.CPP, {}
75 # Other callstacks all get priority 1.
76 if SyzyasanDetector.SYZYASAN_NON_CRASH_CALLSTACK_START_REGEX.match(line):
77 return True, 1, CallStackFormatType.SYZYASAN, LanguageType.CPP, {}
78
79 return False, None, None, None, None
80
81
82 class TsanDetector(CallStackDetector):
83 """Detects the start of a thread sanitizer callstack."""
84 TSAN_CRASH_CALLSTACK_START_PATTERN1 = r'^(Read|Write) of size \d+'
85 TSAN_CRASH_CALLSTACK_START_PATTERN2 = r'^[A-Z]+: ThreadSanitizer'
86 TSAN_ALLOCATION_CALLSTACK_START_PATTERN = (
87 r'^Previous (write|read) of size \d+')
88 TSAN_LOCATION_CALLSTACK_START_PATTERN = (
89 r'^Location is heap block of size \d+')
90
91 TSAN_CRASH_CALLSTACK_START_REGEX = re.compile(
92 '|'.join([TSAN_CRASH_CALLSTACK_START_PATTERN1,
93 TSAN_CRASH_CALLSTACK_START_PATTERN2]))
94
95 TSAN_NON_CRASH_CALLSTACK_START_REGEX = re.compile(
96 '|'.join([TSAN_ALLOCATION_CALLSTACK_START_PATTERN,
97 TSAN_LOCATION_CALLSTACK_START_PATTERN]))
98
99 def IsStartOfNewCallStack(self, line, flags=None):
100 # Crash stack gets priority 0.
101 if TsanDetector.TSAN_CRASH_CALLSTACK_START_REGEX.match(line):
102 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
103
104 # All other stacks get priority 1.
105 if TsanDetector.TSAN_NON_CRASH_CALLSTACK_START_REGEX.match(line):
106 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
107
108 return False, None, None, None, None
109
110
111 class UbsanDetector(CallStackDetector):
112 """Detects the start of a ubsan callstack."""
wrengr 2016/12/22 23:28:36 "a ubsan" -> "an undefined-behavior sanitizer"
Sharu Jiang 2016/12/28 20:16:46 Done.
113 UBSAN_CALLSTACK_START_REGEX = re.compile(r'^.*: runtime error: .*$')
114
115 def IsStartOfNewCallStack(self, line, flags=None):
116 if UbsanDetector.UBSAN_CALLSTACK_START_REGEX.match(line):
117 if flags and flags.Get('is_first_stack_flag'):
118 flags.Set('is_first_stack_flag', False)
119 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
120
121 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
122
123 return False, None, None, None, None
124
125
126 class MsanDetector(CallStackDetector):
127 """Detects the start of a memory sanitizer callstack."""
128 MSAN_CALLSTACK_START_REGEX = re.compile(r'^==(\d+)== ?([A-Z]+:|\w+Sanitizer)')
129 MSAN_CREATION_CALLSTACK_START_MARKER = 'Uninitialized value was created by'
130 MSAN_STORAGE_CALLSTACK_START_MARKER = 'Uninitialized value was stored to'
131
132 def IsStartOfNewCallStack(self, line, flags=None):
133 # Assign the only msan stack priority 0.
134 if MsanDetector.MSAN_CREATION_CALLSTACK_START_MARKER in line:
135 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
136 if MsanDetector.MSAN_STORAGE_CALLSTACK_START_MARKER in line:
137 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
138 msan_callstack_start_regex = (
139 MsanDetector.MSAN_CALLSTACK_START_REGEX.match(line))
140 if msan_callstack_start_regex:
141 return (True, 2, CallStackFormatType.DEFAULT, LanguageType.CPP,
142 {'pid': int(msan_callstack_start_regex.group(1).strip())})
143
144 return False, None, None, None, None
145
146
147 class AsanDetector(CallStackDetector):
148 """Detects the start of an address sanitizer callstack."""
149 ASAN_CRASH_CALLSTACK_START_REGEX1 = re.compile(
150 r'^==(\d+)== ?([A-Z]+:|\w+Sanitizer)')
151 ASAN_CRASH_CALLSTACK_START_REGEX2 = re.compile(
152 r'^(READ|WRITE) of size \d+ at|^backtrace:')
153
154 ASAN_FREED_CALLSTACK_START_PATTERN = (
155 r'^freed by thread T\d+ (.* )?here:')
156 ASAN_ALLOCATION_CALLSTACK_START_PATTERN = (
157 r'^(previously )?allocated by thread T\d+ (.* )?here:')
158 ASAN_OTHER_CALLSTACK_START_PATTERN = (
159 r'^Thread T\d+ (.* )?created by')
160
161 ASAN_NON_CRASH_CALLSTACK_START_PATTERN = re.compile(
162 '|'.join([ASAN_FREED_CALLSTACK_START_PATTERN,
163 ASAN_ALLOCATION_CALLSTACK_START_PATTERN,
164 ASAN_OTHER_CALLSTACK_START_PATTERN]))
165
166 def IsStartOfNewCallStack(self, line, flags=None):
167 metadata = {}
168 asan_crash_callstack_start_regex1_match = (
169 AsanDetector.ASAN_CRASH_CALLSTACK_START_REGEX1.match(line))
170 if asan_crash_callstack_start_regex1_match:
171 metadata['pid'] = int(
172 asan_crash_callstack_start_regex1_match.group(1).strip())
wrengr 2016/12/22 23:28:36 I think it'd be clearer to return (True, 0, DEFAUL
Sharu Jiang 2016/12/28 20:16:46 Done.
173 # Crash stack gets priority 0.
174 if (asan_crash_callstack_start_regex1_match or
175 AsanDetector.ASAN_CRASH_CALLSTACK_START_REGEX2.match(line)):
176 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, metadata
177
178 # All other callstack gets priority 1.
179 if AsanDetector.ASAN_NON_CRASH_CALLSTACK_START_PATTERN.match(line):
180 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, metadata
181
182 return False, None, None, None, None
183
184
185 class ChromeCrashStackDetector(CallStackDetector):
186 """Detects the start of an chromecrash(Fracas/Cracas) callstack."""
187 CHROME_CRASH_CALLSTACK_START_REGEX = re.compile(r'CRASHED \[(.*) @ 0x(.*)\]')
188 JAVA_CALLSTACK_START_REGEX = re.compile(r'\(JAVA\) CRASHED \[(.*) @ 0x(.*)\]')
189
190 def IsStartOfNewCallStack(self, line, flags=None):
191 if ChromeCrashStackDetector.CHROME_CRASH_CALLSTACK_START_REGEX.match(line):
192 # Fracas only provide magic signature stack (crash stack).
193 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {}
194
195 if ChromeCrashStackDetector.JAVA_CALLSTACK_START_REGEX.match(line):
196 return True, 0, CallStackFormatType.DEFAULT, LanguageType.JAVA, {}
197
198 return False, None, None, None, None
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/crash/chromecrash_parser.py » ('j') | appengine/findit/crash/clusterfuzz_parser.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698