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

Side by Side Diff: tools/findit/crash_utils.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 json
5 import time
6 import urllib
7
8
9 def NormalizePathLinux(path):
10 """Normalizes linux path.
11
12 Args:
13 path: a string representing a path
14
15 Returns:
16 A tuple containing a component this path is in (e.g blink, skia, etc)
17 and a path in that component's repository
18 """
19 normalized_path = path
20 # TODO(jeun): integrate with parsing DEPS file
21 if 'WebKit/' in path:
22 component = 'blink'
23 normalized_path = path.split('WebKit/')[1]
24 else:
25 component = 'chromium'
26
27 if normalized_path.startswith(
28 '/b/build/slave/ASAN_Release__symbolized_/build/'):
29 normalized_path = normalized_path.split(
30 '/b/build/slave/ASAN_Release__symbolized_/build/')[1]
31
32 if '../../' in normalized_path:
33 normalized_path = normalized_path.split('../../')[1]
34
35 if 'src/v8/' in normalized_path:
36 component = 'v8'
37 normalized_path = normalized_path.split('src/v8/')[1]
38
39 if './' in normalized_path:
40 normalized_path = normalized_path.split('./')[1]
41
42 if not normalized_path.startswith('src/') and (
43 not normalized_path.startswith('Source/')):
44 normalized_path = 'src/' + normalized_path
45
46 return (component, normalized_path)
47
48
49 def SplitRange(regression):
50 """Splits a range as retrieved from clusterfuzz.
51
52 Args:
53 regression: a string in format 'r1234:r5678'
54
55 Returns:
56 a list containing two numbers represented in string, for example
57 ['1234','5678']
58 """
59 temp = regression.split(':')
60
61 # If regression information is not available, return none
62 if len(temp) != 2:
63 return None
64
65 start_range = temp[0]
66 end_range = temp[1]
67
68 # Check if the range starts with r, such as in 'r10000' format
69 if start_range.startswith('r'):
70 start_range = start_range[1:]
71 if end_range.startswith('r'):
72 end_range = end_range[1:]
73
74 return [start_range, end_range]
75
76
77 def LoadJSON(json_string):
78 """Loads json object from string, or None.
79
80 Args:
81 json_string: a string to get object from.
82
83 Returns:
84 JSON object if the string represents a JSON object, None otherwise
85 """
86 try:
87 data = json.loads(json_string)
88 except ValueError:
89 data = None
90 return data
91
92
93 def GetDataFromURL(url):
94 """Retrieves raw data from URL, tries 10 times.
95
96 Args:
97 url: url to get data from
98
99 Returns:
100 None if the data retrieval fails, or the raw data.
101 """
102 data = None
103 for i in range(10):
104
105 # Retrieves data from URL
106 try:
107 data = urllib.urlopen(url)
108
109 # If retrieval is successful, break from the retry look
110 if data:
111 break
112
113 # If retrieval fails, try after 0.1 second
114 except IOError:
115 time.sleep(0.1)
116 continue
117
118 # If returned data has something in it, return the content
119 if data:
120 return data.read()
121 else:
122 return None
123
124
125 def FindMinLineDistance(crashed_line_list, changed_line_numbers):
126 """Calculates how far the changed line is from one of the crashes.
127
128 Finds the minimum distance between the lines that the file crashed on
129 and the lines that the file changed. For example, if the file crashed on
130 line 200 and the CL changes line 203,204 and 205, the function returns 3.
131
132 Args:
133 crashed_line_list: list of lines that the file crashed on
134 changed_line_numbers: list of lines that the file changed
135
136 Returns:
137 the minimum distance. If either of the input lists is empty,
138 it returns inf.
139
140 """
141 min_distance = float('inf')
142
143 for line in crashed_line_list:
144 for distance in changed_line_numbers:
145 # Find the current distance and update the min if current distance is
146 # less than current min
147 current_distance = abs(line - distance)
148 if current_distance < min_distance:
149 min_distance = current_distance
150
151 return min_distance
152
153
154 def GuessIfSamePath(path1, path2):
155 """Guesses if two paths represent same path.
156
157 Compares the name of the folders in the path (by split('/')), and checks
158 if they match either more than 3 or min of path lengths
159
160 Args:
161 path1: First path
162 path2: Second path to compare
163
164 Returns:
165 True if it they are thought to be a same path, False otherwise
166 """
167 path1 = path1.split('/')
168 path2 = path2.split('/')
169
170 intersection = set(path1).intersection(set(path2))
171 return len(intersection) >= (min(3, min(len(path1), len(path2))))
172
173
174 def FindMinStackFrameNum(stack_frame_index, priorities):
175 """Finds the minimum stack number, from the list of stack numbers.
176
177 Args:
178 stack_frame_index: a list of list containing stack position
179 priorities: a list of of priority for each file
180
181 Returns:
182 inf if stack_frame_index is empty, minimum stack number otherwise
183 """
184 # Get the indexes of the highest priority (or low priority number)
185 highest_priority = min(priorities)
186 highest_priority_indices = []
187 for i in range(len(priorities)):
188 if priorities[i] == highest_priority:
189 highest_priority_indices.append(i)
190
191 # Gather the list of stack frame numbers for the files that change the
192 # crash lines
193 flattened = []
194 for i in highest_priority_indices:
195 flattened += stack_frame_index[i]
196
197 # If no stack frame information is available, return inf. Else, return min
198 if not flattened:
199 return float('inf')
200 else:
201 return min(flattened)
202
203
204 def AddHyperlink(to_add, link):
205 """Returns a string with HTML link tag.
206
207 Args:
208 to_add: a string to add link
209 link: a link to add to the string
210
211 Returns:
212 a string with hyperlink added
213 """
214 return '<a href="%s">%s<\\a>' % (link, to_add)
215
216
217 def PrettifyList(l):
218 """Returns a string representation of a list of ints.
219
220 Args:
221 l: an int list to prettify
222 Returns:
223 a string representation of list
224 """
225 return str(l)[1:-1]
226
227
228 def PrettifyFiles(file_list):
229 """Returns a string representation of a list of file names.
230
231 Args:
232 file_list: a list of tuple, (file_name, file_url)
233 Returns:
234 a string representation of file names
235 """
236 ret = ['\n']
237 for file_name, file_url in file_list:
238 ret.append(' %s\n' % AddHyperlink(file_name, file_url))
239 return ''.join(ret)
240
241
242 def Intersection(crashed_line_list, stack_frame_index, changed_line_numbers):
243 """Finds the overlap betwee changed lines and crashed lines.
244
245 Finds the intersection of the lines that caused the crash and
246 lines that the file changes. The intersection looks within 3 lines
247 of the line that caused the crash.
248
249 Args:
250 crashed_line_list: list of lines that the file crashed on
251 stack_frame_index: list of positions in stack for each of the lines
252 changed_line_numbers: list of lines that the file changed
253
254 Returns:
255 line_intersection: intersection between crashed_line_list and
256 changed_line_numbers
257 stack_frame_index_intersection: stack number for each of the intersections
258 """
259 line_intersection = []
260 stack_frame_index_intersection = []
261
262 # Iterate through the crashed lines, and its occurence in stack
263 for (line, stack_frame_index) in zip(crashed_line_list, stack_frame_index):
264
265 # Also check previous 3 lines
266 line_minus_n = range(line - 3, line + 1)
267
268 for changed_line in changed_line_numbers:
269
270 # If a CL does not change crahsed line, check next line
271 if changed_line not in line_minus_n:
272 continue
273
274 # If the changed line is exactly the crashed line, add that line
275 if line in changed_line_numbers:
276 to_add = line
277
278 # If the changed line is within 3 lines of the crashed line, add the line
279 else:
280 to_add = changed_line
281
282 # Avoid adding the same line twiece
283 if to_add not in line_intersection:
284 line_intersection.append(to_add)
285 stack_frame_index_intersection.append(stack_frame_index)
286
287 break
288
289 return (line_intersection, stack_frame_index_intersection)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698