| Index: appengine/findit/crash/stacktrace.py
|
| diff --git a/appengine/findit/crash/stacktrace.py b/appengine/findit/crash/stacktrace.py
|
| index 797cd88380b03c2f743e1624f4892fa7b0158659..f18b20716206bedce78cdf2500ddc6850a17033b 100644
|
| --- a/appengine/findit/crash/stacktrace.py
|
| +++ b/appengine/findit/crash/stacktrace.py
|
| @@ -2,21 +2,58 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| +import re
|
| +
|
|
|
| class Stacktrace(list):
|
| """Interface Represents Stacktrace object.
|
|
|
| Contains a list of callstacks, because one stacktrace may have more than
|
| one callstacks."""
|
| - def __init__(self):
|
| - super(Stacktrace, self).__init__()
|
| + def __init__(self, frame_list=None, signature=None):
|
| + if frame_list is None:
|
| + frame_list = []
|
| +
|
| + super(Stacktrace, self).__init__(frame_list)
|
| + if signature:
|
| + # Filter out the types of signature, for example [Out of Memory].
|
| + signature = re.sub('[[][^]]*[]]\s*', '', signature)
|
|
|
| - def GetCrashStack(self):
|
| + self.signature = signature
|
| + self._crash_stack = None
|
| +
|
| + @property
|
| + def crash_stack(self):
|
| """Gets the crash stack with the highest (lowest number) priority in
|
| stacktrace."""
|
| if not self:
|
| return None
|
|
|
| - # Return the first stack with the least priority. The smaller the number,
|
| - # the higher the priority beginning with 0.
|
| - return sorted(self, key=lambda stack: stack.priority)[0]
|
| + if self._crash_stack is None and self.signature:
|
| + # For clusterfuzz crash, the signature is crash state, it is usually the
|
| + # top 3 crash functions seperated by '\n'.
|
| + signature_parts = self.signature.split('\n')
|
| +
|
| + def _IsSignatureCallstack(callstack):
|
| + for index, frame in enumerate(callstack):
|
| + for signature_part in signature_parts:
|
| + if signature_part in frame.function:
|
| + return True, index
|
| +
|
| + return False, 0
|
| +
|
| + # Set the crash stack using signature callstack.
|
| + for callstack in self:
|
| + is_signature_callstack, index = _IsSignatureCallstack(callstack)
|
| + if is_signature_callstack:
|
| + # Filter all the stack frames before signature.
|
| + callstack[:] = callstack[index:]
|
| + self._crash_stack = callstack
|
| + break
|
| +
|
| + # If there is no signature callstack, fall back to set crash stack using
|
| + # the first least priority callstack.
|
| + if self._crash_stack is None:
|
| + self._crash_stack = sorted(self, key=lambda stack: stack.priority)[0]
|
| +
|
| + return self._crash_stack
|
|
|