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

Side by Side Diff: tools/findit/stacktrace.py

Issue 430943003: [Findit] Plain objects to represent and parse stack trace. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: changed wrong reference to stack frame Created 6 years, 4 months 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 unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 import os
5 import re
6 import crash_utils
7
8
9 class Stacktrace(object):
10 """Represents Stacktrace object.
11
12 Contains release build stacktrace and debug build stacktrace.
13 """
14
15 def __init__(self, stacktrace, chrome_build):
16 self.stack_list = []
17 self.ParseStacktrace(stacktrace, chrome_build)
18
19 def ParseStacktrace(self, stacktrace, chrome_build):
20 """Parses stacktrace and normalizes it.
21
22 If there are multiple callstacks within the stacktrace,
23 it will parse each of them separately, and store them in the stack_list
24 variable.
25
26 Args:
27 stacktrace: a string containing stacktrace
28 chrome_build: a string containing the job type of the crash
29 """
30 # If the passed in string is empty, the object does not represent anything.
31 if not stacktrace:
32 self.stack_list = None
33 return
34
35 stack_frame_index_pattern = re.compile(r'#(\d+)')
36
37 # Reset the stack list, and assume we start from main thread.
38 self.stack_list = []
39 stack_priority = 0
40 seen_main_thread = False
stgao 2014/07/31 19:48:58 reach_new_callstack?
41 current_stack = CallStack(stack_priority)
42
43 for line in stacktrace:
44 # match the line to see if it is a valid stack frame
stgao 2014/07/31 19:48:58 nit: comment style
45 stack_frame_index_match = stack_frame_index_pattern.match(line)
46
47 # If this line does not represent the crashing information, continue.
48 if not stack_frame_index_match:
49 continue
50
51 # Get the stack frame index from the match
52 stack_frame_index = int(stack_frame_index_match.group(1))
53
54 # If it is 0, we need to check if this is from freed or prev-alloc, or
55 # is from main thead.
56 if stack_frame_index == 0:
57
58 # If this callstack is from main thread, update the boolean.
59 if not seen_main_thread:
60 seen_main_thread = True
61
62 # If this is from freed or prev-alloc, add the callstack we have
63 # to the list of callstacks, and increment the stack priority.
64 else:
65 self.stack_list.append(current_stack)
66 stack_priority += 1
67 current_stack = CallStack(stack_priority)
68
69 # Parse function name, file path and line number from the line.
70 parsed_stack_frame_line = self.ExtractFromStackFrame(
71 line, chrome_build)
72
73 # If the line is malformed, ignore this line. Else, get the info.
74 if not parsed_stack_frame_line:
75 continue
76 (function, file_path, crashed_line_number) = parsed_stack_frame_line
77
78 # Normalize the file path so that it can be compared to repository path.
79 file_name = os.path.basename(file_path)
80 (component, file_path) = crash_utils.NormalizePathLinux(file_path)
81
82 # Currently supports only blink and chromium.
83 if component == 'blink' or component == 'chromium':
84 current_stack.Add(
85 StackFrame(stack_frame_index, component, file_name,
86 function, file_path, crashed_line_number))
87
88 self.stack_list.append(current_stack)
89
90 def ExtractFromStackFrame(self, line, chrome_build):
stgao 2014/07/31 19:48:58 Used within class only. Add underscore before func
91 """Extracts information from a line in stacktrace.
92
93 Args:
94 line: a stacktrace string to extract data from
95 chrome_build: a string containing the job type
96 of this crash (e.g. linux_asan_chrome_mp)
97
98 Returns:
99 A triple containing the name of the function, the path of the file and
100 the line of crash
101 """
102 line_parts = line.split()
103 try:
104 # tsan has different stack frame style from other builds.
105 if chrome_build.startswith('linux_tsan'):
106 file_path_and_line = line_parts[-2]
107 function = ' '.join(line_parts[1:-2])
108
109 else:
110 file_path_and_line = line_parts[-1]
111 function = ' '.join(line_parts[3:-1])
112
113 # Get file path and line info from the line.
114 file_path_and_line = file_path_and_line.split(':')
115 file_path = file_path_and_line[0]
116 crashed_line_number = int(file_path_and_line[1])
117 return (function, file_path, crashed_line_number)
118
119 # Return None if the line is malformed.
120 except IndexError:
121 return None
122 except ValueError:
123 return None
124
125 def __getitem__(self, index):
126 return self.stack_list[index]
127
128 def GetStackFromMainThread(self):
129 return self.stack_list[0]
130
131
132 class CallStack(object):
133 """Represents a call stack within a stacktrace.
134
135 It is a list of StackFrame object, and the stack represented by
136 this object is from main thread, freed thread or previously-allocated thread.
137 """
138
139 def __init__(self, stack_priority):
140 self.frame_list = []
141 self.priority = stack_priority
142
143 def Add(self, stacktrace_line):
144 self.frame_list.append(stacktrace_line)
145
146 def GetFirstN(self, n):
147 return self.frame_list[:n]
148
149
150 class StackFrame(object):
151 """Represents a line in stacktrace.
152
153 Attributes:
154 index: index in the stacktrace
155 component: a component this line represents, such as blink, chrome, etc.
156 file_name: name of the file that crashed
157 function: function that caused the crash
158 file_path: path of the crashed file
159 crashed_line_number: line of the file that caused the crash
160 """
161
162 def __init__(self, stack_frame_index, component, file_name,
163 function, file_path, crashed_line_number):
164 self.index = stack_frame_index
165 self.component = component
166 self.file_name = file_name
167 self.function = function
168 self.file_path = file_path
169 self.crashed_line_number = crashed_line_number
OLDNEW
« tools/findit/component_dictionary.py ('K') | « tools/findit/crash_utils.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698