16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)# Copyright (c) 2014 The Chromium Authors. All rights reserved. 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)# found in the LICENSE file. 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import re 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import crash_utils 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciSYZYASAN_STACK_FRAME_PATTERN = re.compile( 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci r'(CF: )?(.*?)( \(FPO: .*\) )?( \(CONV: .*\) )?\[(.*) @ (\d+)\]') 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFILE_PATH_AND_LINE_PATTERN = re.compile(r'(.*?):(\d+)(:\d+)?') 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class StackFrame(object): 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Represents a frame in stacktrace. 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Attributes: 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) index: An index of the stack frame. 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) component_path: The path of the component this frame represents. 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) component_name: The name of the component this frame represents. 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) file_name: The name of the file that crashed. 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) function: The function that caused the crash. 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) file_path: The path of the crashed file. 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_range: The line of the file that caused the crash. 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def __init__(self, stack_frame_index, component_path, component_name, 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_name, function, file_path, crashed_line_range): 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.index = stack_frame_index 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.component_path = component_path 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.component_name = component_name 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.file_name = file_name 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.function = function 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.file_path = file_path 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.crashed_line_range = crashed_line_range 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class CallStack(object): 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Represents a call stack within a stacktrace. 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) It is a list of StackFrame object, and the object keeps track of whether 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) the stack is crash stack, freed or previously-allocated. 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def __init__(self, stack_priority): 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.frame_list = [] 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.priority = stack_priority 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def Add(self, stacktrace_line): 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.frame_list.append(stacktrace_line) 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def GetTopNFrames(self, n): 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return self.frame_list[:n] 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class Stacktrace(object): 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Represents Stacktrace object. 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Contains a list of callstacks, because one stacktrace might have more than 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) one callstacks. 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def __init__(self, stacktrace, build_type, parsed_deps): 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.stack_list = None 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.ParseStacktrace(stacktrace, build_type, parsed_deps) 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci def ParseStacktrace(self, stacktrace, build_type, parsed_deps): 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Parses stacktrace and normalizes it. 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) If there are multiple callstacks within the stacktrace, 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) it will parse each of them separately, and store them in the stack_list 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) variable. 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Args: 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) stacktrace: A string containing stacktrace. 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) build_type: A string containing the build type of the crash. 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci parsed_deps: A parsed DEPS file to normalize path with. 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # If the passed in string is empty, the object does not represent anything. 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if not stacktrace: 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Reset the stack list. 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.stack_list = [] 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) reached_new_callstack = False 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Note that we do not need exact stack frame index, we only need relative 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # position of a frame within a callstack. The reason for not extracting 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # index from a line is that some stack frames do not have index. 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) stack_frame_index = 0 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_stack = CallStack(-1) 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for line in stacktrace: 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci line = line.strip() 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (is_new_callstack, stack_priority) = self.__IsStartOfNewCallStack( 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) line, build_type) 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if is_new_callstack: 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # If this callstack is crash stack, update the boolean. 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if not reached_new_callstack: 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) reached_new_callstack = True 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) current_stack = CallStack(stack_priority) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # If this is from freed or allocation, add the callstack we have 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # to the list of callstacks, and increment the stack priority. 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else: 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) stack_frame_index = 0 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if current_stack and current_stack.frame_list: 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.stack_list.append(current_stack) 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) current_stack = CallStack(stack_priority) 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Generate stack frame object from the line. 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) parsed_stack_frame = self.__GenerateStackFrame( 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stack_frame_index, line, build_type, parsed_deps) 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # If the line does not represent the stack frame, ignore this line. 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if not parsed_stack_frame: 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) continue 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Add the parsed stack frame object to the current stack. 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) current_stack.Add(parsed_stack_frame) 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) stack_frame_index += 1 1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Add the current callstack only if there are frames in it. 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if current_stack and current_stack.frame_list: 1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self.stack_list.append(current_stack) 1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def __IsStartOfNewCallStack(self, line, build_type): 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Check if this line is the start of the new callstack. 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Since each builds have different format of stacktrace, the logic for 1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) checking the line for all builds is handled in here. 1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Args: 1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) line: Line to check for. 1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) build_type: The name of the build. 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Returns: 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) True if the line is the start of new callstack, False otherwise. If True, 1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) it also returns the priority of the line. 1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if 'syzyasan' in build_type: 1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # In syzyasan build, new stack starts with 'crash stack:', 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # 'freed stack:', etc. 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) callstack_start_pattern = re.compile(r'^(.*) stack:$') 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) match = callstack_start_pattern.match(line) 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # If the line matches the callstack start pattern. 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if match: 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Check the type of the new match. 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) stack_type = match.group(1) 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Crash stack gets priority 0. 1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if stack_type == 'Crash': 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 0) 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Other callstacks all get priority 1. 1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else: 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 1) 1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) elif 'tsan' in build_type: 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Create patterns for each callstack type. 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern1 = re.compile( 1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^(Read|Write) of size \d+') 1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern2 = re.compile( 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci r'^[A-Z]+: ThreadSanitizer') 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) allocation_callstack_start_pattern = re.compile( 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^Previous (write|read) of size \d+') 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) location_callstack_start_pattern = re.compile( 1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^Location is heap block of size \d+') 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Crash stack gets priority 0. 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (crash_callstack_start_pattern1.match(line) or 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern2.match(line)): 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 0) 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # All other stacks get priority 1. 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if allocation_callstack_start_pattern.match(line): 1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 1) 1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if location_callstack_start_pattern.match(line): 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 1) 1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else: 1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # In asan and other build types, crash stack can start 1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # in two different ways. 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern1 = re.compile(r'^==\d+== ?[A-Z]+:') 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) crash_callstack_start_pattern2 = re.compile( 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^(READ|WRITE) of size \d+ at') 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern3 = re.compile(r'^backtrace:') 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) freed_callstack_start_pattern = re.compile( 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^freed by thread T\d+ (.* )?here:') 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) allocation_callstack_start_pattern = re.compile( 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^previously allocated by thread T\d+ (.* )?here:') 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) other_callstack_start_pattern = re.compile( 2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) r'^Thread T\d+ (.* )?created by') 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Crash stack gets priority 0. 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (crash_callstack_start_pattern1.match(line) or 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern2.match(line) or 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_callstack_start_pattern3.match(line)): 2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 0) 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # All other callstack gets priority 1. 2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if freed_callstack_start_pattern.match(line): 2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 1) 2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if allocation_callstack_start_pattern.match(line): 2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 1) 2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if other_callstack_start_pattern.match(line): 2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (True, 1) 2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # If the line does not match any pattern, return false and a dummy for 2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # stack priority. 2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return (False, -1) 2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci def __GenerateStackFrame(self, stack_frame_index, line, build_type, 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci parsed_deps): 2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Extracts information from a line in stacktrace. 2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Args: 2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) stack_frame_index: A stack frame index of this line. 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) line: A stacktrace string to extract data from. 2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) build_type: A string containing the build type 2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) of this crash (e.g. linux_asan_chrome_mp). 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci parsed_deps: A parsed DEPS file to normalize path with. 2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Returns: 2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) A triple containing the name of the function, the path of the file and 2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) the crashed line number. 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) line_parts = line.split() 2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) try: 2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if 'syzyasan' in build_type: 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stack_frame_match = SYZYASAN_STACK_FRAME_PATTERN.match(line) 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if not stack_frame_match: 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_path = stack_frame_match.group(5) 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_range = [int(stack_frame_match.group(6))] 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci function = stack_frame_match.group(2) 2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else: 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if not line_parts[0].startswith('#'): 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if 'tsan' in build_type: 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_path_and_line = line_parts[-2] 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci function = ' '.join(line_parts[1:-2]) 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else: 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_path_and_line = line_parts[-1] 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci function = ' '.join(line_parts[3:-1]) 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # Get file path and line info from the line. 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_path_and_line_match = FILE_PATH_AND_LINE_PATTERN.match( 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_path_and_line) 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # Return None if the file path information is not available 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if not file_path_and_line_match: 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_path = file_path_and_line_match.group(1) 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # Get the crashed line range. For example, file_path:line_number:range. 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_range_num = file_path_and_line_match.group(3) 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if crashed_line_range_num: 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # Strip ':' prefix. 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_range_num = int(crashed_line_range_num[1:]) 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else: 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_range_num = 0 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_number = int(file_path_and_line_match.group(2)) 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # For example, 655:1 has crashed lines 655 and 656. 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_range = \ 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci range(crashed_line_number, 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crashed_line_number + crashed_line_range_num + 1) 2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Return None if the line is malformed. 2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) except IndexError: 2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return None 2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) except ValueError: 2896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return None 2906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Normalize the file path so that it can be compared to repository path. 2926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (component_path, component_name, file_path) = ( 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci crash_utils.NormalizePath(file_path, parsed_deps)) 2946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) # Return a new stack frame object with the parsed information. 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_name = file_path.split('/')[-1] 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # If we have the common stack frame index pattern, then use it 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # since it is more reliable. 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci index_match = re.match('\s*#(\d+)\s.*', line) 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if index_match: 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stack_frame_index = int(index_match.group(1)) 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return StackFrame(stack_frame_index, component_path, component_name, 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_name, function, file_path, crashed_line_range) 3066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def __getitem__(self, index): 3086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return self.stack_list[index] 3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) def GetCrashStack(self): 3116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """Returns the callstack with the highest priority. 3126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Crash stack has priority 0, and allocation/freed/other thread stacks 3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) get priority 1. 3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Returns: 3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) The highest priority callstack in the stacktrace. 3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) """ 3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sorted_stacklist = sorted(self.stack_list, 3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) key=lambda callstack: callstack.priority) 3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return sorted_stacklist[0] 322