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

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

Issue 2588133003: [Predator] Add clusterfuzz callstack filters. (Closed)
Patch Set: Rebase. Created 3 years, 12 months 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
« no previous file with comments | « no previous file | appengine/findit/crash/stacktrace.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import re 5 import re
6 6
7 from crash.stacktrace import CallStack
8 from crash.type_enums import LanguageType
9
7 _INLINE_FUNCTION_FILE_PATH_MARKERS = [ 10 _INLINE_FUNCTION_FILE_PATH_MARKERS = [
8 'third_party/llvm-build/Release+Asserts/include/c++/v1/', 11 'third_party/llvm-build/Release+Asserts/include/c++/v1/',
9 'linux/debian_wheezy_amd64-sysroot/usr/include/c++/4.6/bits/', 12 'linux/debian_wheezy_amd64-sysroot/usr/include/c++/4.6/bits/',
10 'eglibc-3GlaMS/eglibc-2.19/sysdeps/unix/', 13 'eglibc-3GlaMS/eglibc-2.19/sysdeps/unix/',
11 ] 14 ]
12 15
16 # When checking the null pointer dereference, any dereference of an address
17 # within the threshold is considered as null pointer dereference. Be consistent
18 # with the threshold used in Clusterfuzz.
19 NULL_POINTER_DEREFERENCE_THRESHOLD = 4096
20 V8_JIT_CODE_MARKER = 'v8::internal::Invoke'
21 V8_API_H_FILE_PATH = 'src/api.h'
22 V8_API_CC_FILE_PATH = 'src/api.cc'
23 V8_DEP_PATH_MARKER = 'src/v8'
24 BLINK_BINDINGS_GENERATED_PATH_REGEX = re.compile(
25 r'out/[^/]+/gen/blink/bindings/.*')
26 JAVA_JRE_SDK_REGEX = re.compile(
27 r'(java\..*|javax\..*|org\.xml\..*|org\.w3c\..*|'
28 r'org\.omg\..*|org\.ietf\.jgss\..*)')
29
13 30
14 class CallStackFilter(object): 31 class CallStackFilter(object):
15 """Filters frames of a callstack buffer.""" 32 """Filters frames of a callstack buffer."""
16 33
17 def __call__(self, stack_buffer): 34 def __call__(self, stack_buffer):
18 """Returns the stack_buffer with frames filtered. 35 """Returns the stack_buffer with frames filtered.
19 36
20 Args: 37 Args:
21 stack_buffer (CallStackBuffer): stack buffer to be filtered. 38 stack_buffer (CallStackBuffer): stack buffer to be filtered.
22 39
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 def __call__(self, stack_buffer): 76 def __call__(self, stack_buffer):
60 """Returns stack_buffer with only top n frames. 77 """Returns stack_buffer with only top n frames.
61 78
62 If no self.top_n_frames is None, don't do any filtering. 79 If no self.top_n_frames is None, don't do any filtering.
63 """ 80 """
64 if self.top_n_frames is None: 81 if self.top_n_frames is None:
65 return stack_buffer 82 return stack_buffer
66 83
67 stack_buffer.frames = stack_buffer.frames[:self.top_n_frames] 84 stack_buffer.frames = stack_buffer.frames[:self.top_n_frames]
68 return stack_buffer 85 return stack_buffer
86
87
88 class FilterJavaJreSdkFrames(CallStackFilter):
89 """Filters out package names from Java JRE/SDK.
90
91 For example: java.*, javax.*, org.xml.*, org.w3c.*, org.omg.*,
92 org.ietf.jgss.*. These frames are misleading to Predator.
93 """
94 def __call__(self, stack_buffer):
95 if stack_buffer.language_type != LanguageType.JAVA:
96 return stack_buffer
97
98 stack_buffer.frames = filter(
99 lambda frame: not JAVA_JRE_SDK_REGEX.match(frame.function),
100 stack_buffer.frames)
101 return stack_buffer
102
103
104 class KeepV8FramesIfV8GeneratedJITCrash(CallStackFilter):
105 """Keeps v8 frames if conditions met.
106
107 If the top-most frames don't have symbols, but the top frame that does is
108 ``v8::internal::Invoke``, the bug is likely a crash in
109 V8's generated JIT code.
110 """
111 def __call__(self, stack_buffer):
112 if (stack_buffer and V8_JIT_CODE_MARKER in stack_buffer.frames[0].function
113 and stack_buffer.metadata.get('top_frame_has_no_symbols')):
114 stack_buffer.frames = filter(lambda f: V8_DEP_PATH_MARKER in f.dep_path,
115 stack_buffer.frames)
116 return stack_buffer
117
118
119 class FilterV8FramesForV8APIBindingCode(CallStackFilter):
120 """Filters all v8 frames if all conditions met.
121
122 Conditions:
123 (1) src/v8/src/api.h or src/v8/src/api.cc appears as the top file in the stack
124 trace.
125 (2) the second file is not in src/v8/src
126 (e.g. src/out/Release/gen/blink/bindings) or the crash is caused by
127 dereference of null pointer, then V8 should not be responsible for the crash
128 (likely a bindings issue).
129 """
130 def __init__(self, crash_address=None):
131 """
132 Args:
133 crash_address (str): Address where crash happens.
134 """
135 # Record the crash address of the to-be-parsed stack_buffer.
136 self.crash_address = crash_address
137
138 def __call__(self, stack_buffer):
139 if len(stack_buffer.frames) < 2:
140 return stack_buffer
141
142 first_frame_is_api_file = (
143 V8_DEP_PATH_MARKER in stack_buffer.frames[0].dep_path and
144 (V8_API_H_FILE_PATH == stack_buffer.frames[0].file_path or
145 V8_API_CC_FILE_PATH == stack_buffer.frames[0].file_path))
146
147 second_frame_not_from_v8_src = (
148 V8_DEP_PATH_MARKER not in stack_buffer.frames[1].dep_path or
149 not stack_buffer.frames[1].file_path.startswith('src'))
150
151 null_pointer_dereference = False
152 if self.crash_address:
153 try:
154 null_pointer_dereference = int(
155 self.crash_address,
156 base=16) < NULL_POINTER_DEREFERENCE_THRESHOLD
157 except ValueError: # pragma: no cover
158 # some testcases like memcpy-param-overlap have crash addresses like
159 # '[0x621000017d00,0x621000018cea) and [0x621000017d16, 0x621000018d00)'
160 pass
161
162 if (first_frame_is_api_file and (second_frame_not_from_v8_src or
163 null_pointer_dereference)):
164 stack_buffer.frames = filter(
165 lambda f: V8_DEP_PATH_MARKER not in f.dep_path,
166 stack_buffer.frames)
167 # After deleting all v8 frames, if the top n frames are generated code,
168 # need to filter them out.
169 top_n_generated_code_frames = 0
170 for frame in stack_buffer.frames:
171 if not BLINK_BINDINGS_GENERATED_PATH_REGEX.match(frame.file_path):
172 break
173 top_n_generated_code_frames += 1
174 stack_buffer.frames = stack_buffer.frames[top_n_generated_code_frames:]
175
176 return stack_buffer
177
178
179 class FilterFramesAfterBlinkGeneratedCode(CallStackFilter):
180 """Filters all the frames after blink generated code."""
181 def __call__(self, stack_buffer):
182 for index, frame in enumerate(stack_buffer):
183 if BLINK_BINDINGS_GENERATED_PATH_REGEX.match(frame.file_path):
184 stack_buffer.frames = stack_buffer.frames[:index]
185 break
186
187 return stack_buffer
188
189
190 class FilterV8FramesIfV8NotInTopFrames(CallStackFilter):
191 """Filters all v8 frames if there is no v8 frames in top_n_frames."""
192 def __init__(self, top_n_frames=4):
193 self.top_n_frames = top_n_frames
194
195 def __call__(self, stack_buffer):
196 need_filter_v8 = False
197 for index, frame in enumerate(stack_buffer):
198 if index >= self.top_n_frames:
199 need_filter_v8 = True
200 break
201
202 if V8_DEP_PATH_MARKER in frame.dep_path:
203 break
204
205 if not need_filter_v8:
206 return stack_buffer
207
208 stack_buffer.frames = filter(
209 lambda f: V8_DEP_PATH_MARKER not in f.dep_path, stack_buffer.frames)
210
211 return stack_buffer
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/crash/stacktrace.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698