OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 | 2 |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 from third_party import asan_symbolize | 7 from third_party import asan_symbolize |
8 | 8 |
9 import argparse | 9 import argparse |
10 import base64 | 10 import base64 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 # is located in the product dir. | 156 # is located in the product dir. |
157 outermost_bundle = bundle_positions[0] | 157 outermost_bundle = bundle_positions[0] |
158 product_dir = path_parts[:outermost_bundle] | 158 product_dir = path_parts[:outermost_bundle] |
159 # In case 2 this is the same as |outermost_bundle|. | 159 # In case 2 this is the same as |outermost_bundle|. |
160 innermost_bundle = bundle_positions[-1] | 160 innermost_bundle = bundle_positions[-1] |
161 dsym_path = product_dir + [path_parts[innermost_bundle]] | 161 dsym_path = product_dir + [path_parts[innermost_bundle]] |
162 result = '%s.dSYM' % os.path.join(*dsym_path) | 162 result = '%s.dSYM' % os.path.join(*dsym_path) |
163 return [result] | 163 return [result] |
164 | 164 |
165 | 165 |
166 # We want our output to match base::EscapeJSONString(), which produces | |
167 # doubly-escaped strings. The first escaping pass is handled by this class. The | |
168 # second pass happens when JSON data is dumped to file. | |
169 class StringEncoder(json.JSONEncoder): | |
170 def __init__(self): | |
171 json.JSONEncoder.__init__(self) | |
172 | |
173 def encode(self, s): | |
174 assert(isinstance(s, basestring)) | |
175 # Don't die on invalid utf-8 sequences. | |
176 s = s.decode('utf-8', 'replace') | |
177 encoded = json.JSONEncoder.encode(self, s) | |
178 assert(len(encoded) >= 2) | |
179 assert(encoded[0] == '"') | |
180 assert(encoded[-1] == '"') | |
181 encoded = encoded[1:-1] | |
182 # Special case from base::EscapeJSONString(). | |
183 encoded = encoded.replace('<', '\u003C') | |
184 return encoded | |
185 | |
186 | |
187 class JSONTestRunSymbolizer(object): | 166 class JSONTestRunSymbolizer(object): |
188 def __init__(self, symbolization_loop): | 167 def __init__(self, symbolization_loop): |
189 self.symbolization_loop = symbolization_loop | 168 self.symbolization_loop = symbolization_loop |
190 | 169 |
191 def symbolize_snippet(self, snippet): | 170 def symbolize_snippet(self, snippet): |
192 symbolized_lines = [] | 171 symbolized_lines = [] |
193 for line in snippet.split('\n'): | 172 for line in snippet.split('\n'): |
194 symbolized_lines += self.symbolization_loop.process_line(line) | 173 symbolized_lines += self.symbolization_loop.process_line(line) |
195 return '\n'.join(symbolized_lines) | 174 return '\n'.join(symbolized_lines) |
196 | 175 |
197 def symbolize(self, test_run): | 176 def symbolize(self, test_run): |
198 original_snippet = base64.b64decode(test_run['output_snippet_base64']) | 177 original_snippet = base64.b64decode(test_run['output_snippet_base64']) |
199 symbolized_snippet = self.symbolize_snippet(original_snippet) | 178 symbolized_snippet = self.symbolize_snippet(original_snippet) |
200 if symbolized_snippet == original_snippet: | 179 if symbolized_snippet == original_snippet: |
201 # No sanitizer reports in snippet. | 180 # No sanitizer reports in snippet. |
202 return | 181 return |
203 | 182 |
204 test_run['original_output_snippet'] = test_run['output_snippet'] | 183 test_run['original_output_snippet'] = test_run['output_snippet'] |
205 test_run['original_output_snippet_base64'] = \ | 184 test_run['original_output_snippet_base64'] = \ |
206 test_run['output_snippet_base64'] | 185 test_run['output_snippet_base64'] |
207 | 186 |
208 escaped_snippet = StringEncoder().encode(symbolized_snippet) | 187 test_run['output_snippet'] = symbolized_snippet |
209 test_run['output_snippet'] = escaped_snippet | |
210 test_run['output_snippet_base64'] = \ | 188 test_run['output_snippet_base64'] = \ |
211 base64.b64encode(symbolized_snippet) | 189 base64.b64encode(symbolized_snippet) |
212 test_run['snippet_processed_by'] = 'asan_symbolize.py' | 190 test_run['snippet_processed_by'] = 'asan_symbolize.py' |
213 # Originally, "lossless" refers to "no Unicode data lost while encoding the | |
214 # string". However, since we're applying another kind of transformation | |
215 # (symbolization), it doesn't seem right to consider the snippet lossless. | |
216 test_run['losless_snippet'] = False | |
217 | 191 |
218 | 192 |
219 def symbolize_snippets_in_json(filename, symbolization_loop): | 193 def symbolize_snippets_in_json(filename, symbolization_loop): |
220 with open(filename, 'r') as f: | 194 with open(filename, 'r') as f: |
221 json_data = json.load(f) | 195 json_data = json.load(f) |
222 | 196 |
223 test_run_symbolizer = JSONTestRunSymbolizer(symbolization_loop) | 197 test_run_symbolizer = JSONTestRunSymbolizer(symbolization_loop) |
224 for iteration_data in json_data['per_iteration_data']: | 198 for iteration_data in json_data['per_iteration_data']: |
225 for test_name, test_runs in iteration_data.iteritems(): | 199 for test_name, test_runs in iteration_data.iteritems(): |
226 for test_run in test_runs: | 200 for test_run in test_runs: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 | 236 |
263 if args.test_summary_json_file: | 237 if args.test_summary_json_file: |
264 symbolize_snippets_in_json(args.test_summary_json_file, loop) | 238 symbolize_snippets_in_json(args.test_summary_json_file, loop) |
265 else: | 239 else: |
266 # Process stdin. | 240 # Process stdin. |
267 asan_symbolize.logfile = sys.stdin | 241 asan_symbolize.logfile = sys.stdin |
268 loop.process_logfile() | 242 loop.process_logfile() |
269 | 243 |
270 if __name__ == '__main__': | 244 if __name__ == '__main__': |
271 main() | 245 main() |
OLD | NEW |