OLD | NEW |
---|---|
(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 | |
5 import logging | |
6 | |
7 import chromium_deps | |
8 import crash_utils | |
9 import findit_for_crash as findit | |
10 import stacktrace | |
11 | |
12 | |
13 def SplitStacktrace(stacktrace_string): | |
14 """Preprocesses stacktrace string into two parts, release and debug. | |
15 | |
16 Args: | |
17 stacktrace_string: A string representation of stacktrace, | |
18 in clusterfuzz format. | |
19 | |
20 Returns: | |
21 A tuple of list of strings, release build stacktrace and | |
22 debug build stacktrace. | |
23 """ | |
24 # Make sure we only parse release/debug build stacktrace, and ignore | |
25 # unsymbolised stacktrace. | |
26 in_release_or_debug_stacktrace = False | |
27 release_build_stacktrace_lines = None | |
28 debug_build_stacktrace_lines = None | |
29 current_stacktrace_lines = [] | |
30 | |
31 # Iterate through all lines in stacktrace. | |
32 for line in stacktrace_string.splitlines(): | |
33 line = line.strip() | |
34 | |
35 # If the line starts with +, it signifies the start of new stacktrace. | |
36 if line.startswith('+'): | |
37 if 'Release Build Stacktrace' in line: | |
38 in_release_or_debug_stacktrace = True | |
39 current_stacktrace_lines = [] | |
40 release_build_stacktrace_lines = current_stacktrace_lines | |
41 | |
42 elif 'Debug Build Stacktrace' in line: | |
43 in_release_or_debug_stacktrace = True | |
44 current_stacktrace_lines = [] | |
45 debug_build_stacktrace_lines = current_stacktrace_lines | |
46 | |
47 # If the stacktrace is neither release/debug build stacktrace, ignore | |
48 # all lines after it until we encounter release/debug build stacktrace. | |
49 else: | |
50 in_release_or_debug_stacktrace = False | |
51 | |
52 # This case, it must be that the line is an actual stack frame, so add to | |
53 # the current stacktrace. | |
54 elif in_release_or_debug_stacktrace: | |
55 current_stacktrace_lines.append(line) | |
56 | |
57 return (release_build_stacktrace_lines, debug_build_stacktrace_lines) | |
58 | |
59 | |
60 def FindCulpritCLs(stacktrace_string, | |
61 build_type, | |
62 chrome_regression=None, | |
63 component_regression=None, | |
64 chrome_crash_revision=None, | |
65 component_crash_revision=None, | |
66 crashing_component=None): | |
67 """Returns json format of the result, a list of result.Result objects. | |
stgao
2014/08/18 22:37:07
Seems json format is wrong now?
jeun
2014/08/18 23:52:13
Done.
| |
68 | |
69 Args: | |
70 stacktrace_string: A string representing stacktrace. | |
71 build_type: The type of the job. | |
72 chrome_regression: A string, chrome regression from clusterfuzz, in format | |
73 '123456:123457' | |
74 component_regression: A string, component regression in the same format. | |
75 chrome_crash_revision: A crash revision of chrome, in string. | |
76 component_crash_revision: A crash revision of the component, | |
77 if component build. | |
78 crashing_component: Yet to be decided. | |
79 | |
80 Returns: | |
81 A list of result objects, along with the short description on where the | |
82 result is from. | |
83 """ | |
84 build_type = build_type.lower() | |
85 if 'android' in build_type or 'syzyasan' in build_type: | |
Martin Barbella
2014/08/19 02:51:35
Why are these job types being skipped explicitly?
jeun
2014/08/19 18:30:06
The stacktrace parsing for them is not supported.
| |
86 return ('This build type is currently not supported.', []) | |
87 | |
88 logging.basicConfig(filename='errors.log', level=logging.WARNING, | |
stgao
2014/08/18 22:37:07
Findit should not write any log.
It is the respon
jeun
2014/08/18 23:52:13
Does this mean anything other than this file shoul
| |
89 filemode='w+') | |
90 | |
91 crash_revision_dict = {} | |
92 regression_dict = {} | |
93 | |
94 # TODO(jeun): Come up with a good way to connect crashing component name to | |
Martin Barbella
2014/08/19 02:51:35
What work is still needed to be done here? I thoug
jeun
2014/08/19 18:30:05
Since we started parsing DEPS file for regression
| |
95 # its path. | |
96 if component_regression or component_crash_revision: | |
97 return ('This feature is not supported.', []) | |
stgao
2014/08/18 22:37:07
"Component builds are not supported yet."
jeun
2014/08/18 23:52:13
Done.
| |
98 | |
99 # If chrome regression is available, parse DEPS file. | |
100 chrome_regression = crash_utils.SplitRange(chrome_regression) | |
101 if chrome_regression: | |
102 chrome_regression_start = chrome_regression[0] | |
103 chrome_regression_end = chrome_regression[1] | |
104 | |
105 # If the regression is not reliable, do not parse regression information. | |
Martin Barbella
2014/08/19 02:51:35
A regression range starting with 0 has nothing to
jeun
2014/08/19 18:30:05
Done.
| |
106 if chrome_regression_start != '0': | |
107 regression_dict = chromium_deps.GetChromiumComponentRange( | |
108 chrome_regression_start, chrome_regression_end) | |
109 | |
110 # Parse crash revision. | |
111 if chrome_crash_revision: | |
112 crash_revision_dict = chromium_deps.GetChromiumComponents( | |
stgao
2014/08/18 22:37:06
Do we need to verify |chrome_crash_revision| is no
jeun
2014/08/18 23:52:13
Yes, in case we only have component crash revision
| |
113 chrome_crash_revision) | |
114 | |
115 # Parsed DEPS is used to normalize the stacktrace. Since parsed regression | |
116 # and parsed crash state essentially contain same information, use either. | |
117 if regression_dict: | |
118 parsed_deps = regression_dict | |
119 elif crash_revision_dict: | |
120 parsed_deps = crash_revision_dict | |
121 else: | |
122 return ('No regression and crash revision information available.', []) | |
Martin Barbella
2014/08/19 02:51:35
If someone runs into an error, they probably don't
jeun
2014/08/19 18:30:05
Done.
| |
123 | |
124 # Split stacktrace into release build/debug build and parse them. | |
125 (release_build_stacktrace, debug_build_stacktrace) = SplitStacktrace( | |
126 stacktrace_string) | |
127 parsed_release_build_stacktrace = stacktrace.Stacktrace( | |
128 release_build_stacktrace, build_type, parsed_deps) | |
129 parsed_debug_build_stacktrace = stacktrace.Stacktrace( | |
130 debug_build_stacktrace, build_type, parsed_deps) | |
131 | |
132 # Get a highest priority callstack from stacktrace, with release build | |
133 # stacktrace in higher priority than debug build stacktace. | |
134 if parsed_release_build_stacktrace.stack_list: | |
135 main_stack = parsed_release_build_stacktrace.GetCrashStack() | |
stgao
2014/08/18 22:37:06
What's main stack? What it is for? Why only handle
jeun
2014/08/18 23:52:13
Done.
| |
136 elif parsed_debug_build_stacktrace.stack_list: | |
137 main_stack = parsed_debug_build_stacktrace.GetCrashStack() | |
138 else: | |
139 return ('Stacktrace is malformed.', []) | |
140 | |
141 # Run the algorithm on the parsed stacktrace, and return the JSON. | |
stgao
2014/08/18 22:37:07
We are not returning JSON any more, right?
jeun
2014/08/18 23:52:13
Done.
| |
142 stacktrace_list = [parsed_release_build_stacktrace, | |
143 parsed_debug_build_stacktrace] | |
144 return findit.FindItForCrash( | |
145 stacktrace_list, main_stack, regression_dict, crash_revision_dict) | |
OLD | NEW |