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

Unified Diff: appengine/findit/crash/callstack_filters.py

Issue 2588133003: [Predator] Add clusterfuzz callstack filters. (Closed)
Patch Set: Rebase. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | appengine/findit/crash/stacktrace.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/findit/crash/callstack_filters.py
diff --git a/appengine/findit/crash/callstack_filters.py b/appengine/findit/crash/callstack_filters.py
index d0d62528fcd723516f5faad591ecc084ed527c1b..61e2bd732fd8b3d9ee8e949f48cfe003a85d9e43 100644
--- a/appengine/findit/crash/callstack_filters.py
+++ b/appengine/findit/crash/callstack_filters.py
@@ -4,12 +4,29 @@
import re
+from crash.stacktrace import CallStack
+from crash.type_enums import LanguageType
+
_INLINE_FUNCTION_FILE_PATH_MARKERS = [
'third_party/llvm-build/Release+Asserts/include/c++/v1/',
'linux/debian_wheezy_amd64-sysroot/usr/include/c++/4.6/bits/',
'eglibc-3GlaMS/eglibc-2.19/sysdeps/unix/',
]
+# When checking the null pointer dereference, any dereference of an address
+# within the threshold is considered as null pointer dereference. Be consistent
+# with the threshold used in Clusterfuzz.
+NULL_POINTER_DEREFERENCE_THRESHOLD = 4096
+V8_JIT_CODE_MARKER = 'v8::internal::Invoke'
+V8_API_H_FILE_PATH = 'src/api.h'
+V8_API_CC_FILE_PATH = 'src/api.cc'
+V8_DEP_PATH_MARKER = 'src/v8'
+BLINK_BINDINGS_GENERATED_PATH_REGEX = re.compile(
+ r'out/[^/]+/gen/blink/bindings/.*')
+JAVA_JRE_SDK_REGEX = re.compile(
+ r'(java\..*|javax\..*|org\.xml\..*|org\.w3c\..*|'
+ r'org\.omg\..*|org\.ietf\.jgss\..*)')
+
class CallStackFilter(object):
"""Filters frames of a callstack buffer."""
@@ -66,3 +83,129 @@ class KeepTopNFrames(CallStackFilter):
stack_buffer.frames = stack_buffer.frames[:self.top_n_frames]
return stack_buffer
+
+
+class FilterJavaJreSdkFrames(CallStackFilter):
+ """Filters out package names from Java JRE/SDK.
+
+ For example: java.*, javax.*, org.xml.*, org.w3c.*, org.omg.*,
+ org.ietf.jgss.*. These frames are misleading to Predator.
+ """
+ def __call__(self, stack_buffer):
+ if stack_buffer.language_type != LanguageType.JAVA:
+ return stack_buffer
+
+ stack_buffer.frames = filter(
+ lambda frame: not JAVA_JRE_SDK_REGEX.match(frame.function),
+ stack_buffer.frames)
+ return stack_buffer
+
+
+class KeepV8FramesIfV8GeneratedJITCrash(CallStackFilter):
+ """Keeps v8 frames if conditions met.
+
+ If the top-most frames don't have symbols, but the top frame that does is
+ ``v8::internal::Invoke``, the bug is likely a crash in
+ V8's generated JIT code.
+ """
+ def __call__(self, stack_buffer):
+ if (stack_buffer and V8_JIT_CODE_MARKER in stack_buffer.frames[0].function
+ and stack_buffer.metadata.get('top_frame_has_no_symbols')):
+ stack_buffer.frames = filter(lambda f: V8_DEP_PATH_MARKER in f.dep_path,
+ stack_buffer.frames)
+ return stack_buffer
+
+
+class FilterV8FramesForV8APIBindingCode(CallStackFilter):
+ """Filters all v8 frames if all conditions met.
+
+ Conditions:
+ (1) src/v8/src/api.h or src/v8/src/api.cc appears as the top file in the stack
+ trace.
+ (2) the second file is not in src/v8/src
+ (e.g. src/out/Release/gen/blink/bindings) or the crash is caused by
+ dereference of null pointer, then V8 should not be responsible for the crash
+ (likely a bindings issue).
+ """
+ def __init__(self, crash_address=None):
+ """
+ Args:
+ crash_address (str): Address where crash happens.
+ """
+ # Record the crash address of the to-be-parsed stack_buffer.
+ self.crash_address = crash_address
+
+ def __call__(self, stack_buffer):
+ if len(stack_buffer.frames) < 2:
+ return stack_buffer
+
+ first_frame_is_api_file = (
+ V8_DEP_PATH_MARKER in stack_buffer.frames[0].dep_path and
+ (V8_API_H_FILE_PATH == stack_buffer.frames[0].file_path or
+ V8_API_CC_FILE_PATH == stack_buffer.frames[0].file_path))
+
+ second_frame_not_from_v8_src = (
+ V8_DEP_PATH_MARKER not in stack_buffer.frames[1].dep_path or
+ not stack_buffer.frames[1].file_path.startswith('src'))
+
+ null_pointer_dereference = False
+ if self.crash_address:
+ try:
+ null_pointer_dereference = int(
+ self.crash_address,
+ base=16) < NULL_POINTER_DEREFERENCE_THRESHOLD
+ except ValueError: # pragma: no cover
+ # some testcases like memcpy-param-overlap have crash addresses like
+ # '[0x621000017d00,0x621000018cea) and [0x621000017d16, 0x621000018d00)'
+ pass
+
+ if (first_frame_is_api_file and (second_frame_not_from_v8_src or
+ null_pointer_dereference)):
+ stack_buffer.frames = filter(
+ lambda f: V8_DEP_PATH_MARKER not in f.dep_path,
+ stack_buffer.frames)
+ # After deleting all v8 frames, if the top n frames are generated code,
+ # need to filter them out.
+ top_n_generated_code_frames = 0
+ for frame in stack_buffer.frames:
+ if not BLINK_BINDINGS_GENERATED_PATH_REGEX.match(frame.file_path):
+ break
+ top_n_generated_code_frames += 1
+ stack_buffer.frames = stack_buffer.frames[top_n_generated_code_frames:]
+
+ return stack_buffer
+
+
+class FilterFramesAfterBlinkGeneratedCode(CallStackFilter):
+ """Filters all the frames after blink generated code."""
+ def __call__(self, stack_buffer):
+ for index, frame in enumerate(stack_buffer):
+ if BLINK_BINDINGS_GENERATED_PATH_REGEX.match(frame.file_path):
+ stack_buffer.frames = stack_buffer.frames[:index]
+ break
+
+ return stack_buffer
+
+
+class FilterV8FramesIfV8NotInTopFrames(CallStackFilter):
+ """Filters all v8 frames if there is no v8 frames in top_n_frames."""
+ def __init__(self, top_n_frames=4):
+ self.top_n_frames = top_n_frames
+
+ def __call__(self, stack_buffer):
+ need_filter_v8 = False
+ for index, frame in enumerate(stack_buffer):
+ if index >= self.top_n_frames:
+ need_filter_v8 = True
+ break
+
+ if V8_DEP_PATH_MARKER in frame.dep_path:
+ break
+
+ if not need_filter_v8:
+ return stack_buffer
+
+ stack_buffer.frames = filter(
+ lambda f: V8_DEP_PATH_MARKER not in f.dep_path, stack_buffer.frames)
+
+ return stack_buffer
« 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