Chromium Code Reviews| 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 from collections import namedtuple | 5 from collections import namedtuple |
| 6 import copy | 6 import copy |
| 7 import logging | 7 import logging |
| 8 import math | |
| 8 import re | 9 import re |
| 9 | 10 |
| 10 from crash import parse_util | 11 from crash import parse_util |
| 11 from crash.type_enums import CallStackFormatType | 12 from crash.type_enums import CallStackFormatType |
| 12 from crash.type_enums import LanguageType | 13 from crash.type_enums import LanguageType |
| 13 | 14 |
| 14 # Used to parse a line into StackFrame of a Callstack. | 15 # Used to parse a line into StackFrame of a Callstack. |
| 15 CALLSTACK_FORMAT_TO_PATTERN = { | 16 CALLSTACK_FORMAT_TO_PATTERN = { |
| 16 CallStackFormatType.JAVA: re.compile( | 17 CallStackFormatType.JAVA: re.compile( |
| 17 r'at ([A-Za-z0-9$._<>]+)\(\w+(\.java)?:(\d+)\)'), | 18 r'at ([A-Za-z0-9$._<>]+)\(\w+(\.java)?:(\d+)\)'), |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 __bool__ = __nonzero__ | 303 __bool__ = __nonzero__ |
| 303 | 304 |
| 304 def __iter__(self): | 305 def __iter__(self): |
| 305 """Iterator over the stacks in this trace.""" | 306 """Iterator over the stacks in this trace.""" |
| 306 return iter(self.stacks) | 307 return iter(self.stacks) |
| 307 | 308 |
| 308 | 309 |
| 309 class StacktraceBuffer(object): | 310 class StacktraceBuffer(object): |
| 310 """A Mutable type to simplify constructing ``Stacktrace`` objects. | 311 """A Mutable type to simplify constructing ``Stacktrace`` objects. |
| 311 | 312 |
| 312 The class can be converted to immutable stacktrace. | 313 The class can be converted to immutable stacktrace. |
|
wrengr
2016/12/22 22:42:59
this paragraph should be formatted to avoid weird
Sharu Jiang
2016/12/23 00:26:20
Done.
| |
| 313 using ``ToStacktrace``. | 314 using ``ToStacktrace``. |
| 314 Note, to make this class fully mutable, it should contain CallStackBuffer | 315 Note, to make this class fully mutable, it should contain CallStackBuffer |
| 315 list instead of CallStack list. | 316 list instead of CallStack list. |
| 316 """ | 317 """ |
| 317 def __init__(self, stacks=None, signature=None): | 318 def __init__(self, stacks=None, signature=None, filters=None): |
| 318 """Initialize StacktraceBuffer instance. | 319 """Initialize StacktraceBuffer instance. |
| 319 | 320 |
| 320 Args: | 321 Args: |
| 321 stacks (list of CallStackBuffer): CallStackBuffer objects to | 322 stacks (list of CallStackBuffer): CallStackBuffer objects to |
| 322 build stacktrace. | 323 build stacktrace. |
| 323 signature (str): signagure is used to determine the crash stack. | 324 signature (str): The signagure is used to determine the crash stack. |
|
wrengr
2016/12/22 22:42:59
"signagure" -> "signature"
Sharu Jiang
2016/12/23 00:26:20
Done.
| |
| 325 filters (list of CallStackBuffer): List of filters to filter stack buffer. | |
|
wrengr
2016/12/22 22:43:00
Those aren't CallStackBuffers...
"filters to filt
Sharu Jiang
2016/12/23 00:26:19
Oops, corrected.
| |
| 324 """ | 326 """ |
| 325 self.stacks = stacks or [] | 327 self.stacks = stacks or [] |
| 326 if signature: | 328 if signature: |
| 327 # Filter out the types of signature, for example [Out of Memory]. | 329 # Filter out the types of signature, for example [Out of Memory]. |
| 328 signature = re.sub('[[][^]]*[]]\s*', '', signature) | 330 signature = re.sub('[[][^]]*[]]\s*', '', signature) |
| 329 # For clusterfuzz crash, the signature is crash state. It is | 331 # For clusterfuzz crash, the signature is crash state. It is |
| 330 # usually the top 3 important stack frames separated by '\n'. | 332 # usually the top 3 important stack frames separated by '\n'. |
| 331 self.signature_parts = signature.splitlines() | 333 self.signature_parts = signature.splitlines() |
| 332 else: | 334 else: |
| 333 self.signature_parts = None | 335 self.signature_parts = None |
| 336 self.filters = filters | |
|
wrengr
2016/12/22 22:42:59
should have a blank line before this, iirc
Sharu Jiang
2016/12/23 00:26:20
Done.
| |
| 334 | 337 |
| 335 def __nonzero__(self): | 338 def __nonzero__(self): |
| 336 """Returns whether this trace buffer is empty.""" | 339 """Returns whether this trace buffer is empty.""" |
| 337 return bool(self.stacks) | 340 return bool(self.stacks) |
| 338 __bool__ = __nonzero__ | 341 __bool__ = __nonzero__ |
| 339 | 342 |
| 343 def AddFilteredStack(self, stack_buffer): | |
| 344 """Filters stack_buffer and add it to stacks if it's not empty.""" | |
| 345 # If the callstack is the initial one (infinte priority) or empty, return | |
| 346 # None. | |
| 347 if math.isinf(stack_buffer.priority) or not stack_buffer.frames: | |
| 348 return | |
| 349 | |
| 350 if self.filters: | |
| 351 for stack_filter in self.filters: | |
|
wrengr
2016/12/22 22:42:59
``if filters: for f in filters:...`` -> ``for f in
Sharu Jiang
2016/12/23 00:26:19
Done.
| |
| 352 stack_buffer = stack_filter(stack_buffer) | |
| 353 if not stack_buffer: | |
| 354 return | |
| 355 | |
| 356 self.stacks.append(stack_buffer) | |
| 357 | |
| 340 def ToStacktrace(self): | 358 def ToStacktrace(self): |
| 341 """Converts to ``Stacktrace`` object.""" | 359 """Converts to ``Stacktrace`` object.""" |
| 342 if not self: | 360 if not self: |
| 343 return None | 361 return None |
| 344 | 362 |
| 345 # Get the callstack with the highest priority (i.e., whose priority | 363 # Get the callstack with the highest priority (i.e., whose priority |
| 346 # field is numerically the smallest) in the stacktrace. | 364 # field is numerically the smallest) in the stacktrace. |
| 347 crash_stack_index = None | 365 crash_stack_index = None |
| 348 if self.signature_parts: | 366 if self.signature_parts: |
| 349 def _IsSignatureCallstack(callstack): | 367 def _IsSignatureCallstack(callstack): |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 369 for stack_buffer in self.stacks] | 387 for stack_buffer in self.stacks] |
| 370 | 388 |
| 371 if crash_stack_index is None: | 389 if crash_stack_index is None: |
| 372 # If there is no signature callstack, fall back to set crash stack using | 390 # If there is no signature callstack, fall back to set crash stack using |
| 373 # the first least priority callstack. | 391 # the first least priority callstack. |
| 374 crash_stack = min(callstacks, key=lambda stack: stack.priority) | 392 crash_stack = min(callstacks, key=lambda stack: stack.priority) |
| 375 else: | 393 else: |
| 376 crash_stack = callstacks[crash_stack_index] | 394 crash_stack = callstacks[crash_stack_index] |
| 377 | 395 |
| 378 return Stacktrace(tuple(callstacks), crash_stack) | 396 return Stacktrace(tuple(callstacks), crash_stack) |
| OLD | NEW |