| OLD | NEW |
| 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 |
| 6 |
| 5 | 7 |
| 6 class Stacktrace(list): | 8 class Stacktrace(list): |
| 7 """Interface Represents Stacktrace object. | 9 """Interface Represents Stacktrace object. |
| 8 | 10 |
| 9 Contains a list of callstacks, because one stacktrace may have more than | 11 Contains a list of callstacks, because one stacktrace may have more than |
| 10 one callstacks.""" | 12 one callstacks.""" |
| 11 def __init__(self): | 13 def __init__(self, frame_list=None, signature=None): |
| 12 super(Stacktrace, self).__init__() | 14 if frame_list is None: |
| 15 frame_list = [] |
| 13 | 16 |
| 14 def GetCrashStack(self): | 17 super(Stacktrace, self).__init__(frame_list) |
| 18 if signature: |
| 19 # Filter out the types of signature, for example [Out of Memory]. |
| 20 signature = re.sub('[[][^]]*[]]\s*', '', signature) |
| 21 |
| 22 self.signature = signature |
| 23 self._crash_stack = None |
| 24 |
| 25 @property |
| 26 def crash_stack(self): |
| 15 """Gets the crash stack with the highest (lowest number) priority in | 27 """Gets the crash stack with the highest (lowest number) priority in |
| 16 stacktrace.""" | 28 stacktrace.""" |
| 17 if not self: | 29 if not self: |
| 18 return None | 30 return None |
| 19 | 31 |
| 20 # Return the first stack with the least priority. The smaller the number, | 32 if self._crash_stack is None and self.signature: |
| 21 # the higher the priority beginning with 0. | 33 # For clusterfuzz crash, the signature is crash state, it is usually the |
| 22 return sorted(self, key=lambda stack: stack.priority)[0] | 34 # top 3 crash functions seperated by '\n'. |
| 35 signature_parts = self.signature.split('\n') |
| 36 |
| 37 def _IsSignatureCallstack(callstack): |
| 38 for index, frame in enumerate(callstack): |
| 39 for signature_part in signature_parts: |
| 40 if signature_part in frame.function: |
| 41 return True, index |
| 42 |
| 43 return False, 0 |
| 44 |
| 45 # Set the crash stack using signature callstack. |
| 46 for callstack in self: |
| 47 is_signature_callstack, index = _IsSignatureCallstack(callstack) |
| 48 if is_signature_callstack: |
| 49 # Filter all the stack frames before signature. |
| 50 callstack[:] = callstack[index:] |
| 51 self._crash_stack = callstack |
| 52 break |
| 53 |
| 54 # If there is no signature callstack, fall back to set crash stack using |
| 55 # the first least priority callstack. |
| 56 if self._crash_stack is None: |
| 57 self._crash_stack = sorted(self, key=lambda stack: stack.priority)[0] |
| 58 |
| 59 return self._crash_stack |
| OLD | NEW |