OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2013 The Chromium Authors. All rights reserved. | 3 # Copyright 2013 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 # Find the most recent tombstone file(s) on all connected devices | 7 # Find the most recent tombstone file(s) on all connected devices |
8 # and prints their stacks. | 8 # and prints their stacks. |
9 # | 9 # |
10 # Assumes tombstone file was created with current symbols. | 10 # Assumes tombstone file was created with current symbols. |
11 | 11 |
12 import argparse | 12 import argparse |
13 import datetime | 13 import datetime |
14 import logging | 14 import logging |
15 import multiprocessing | 15 import multiprocessing |
16 import os | 16 import os |
17 import re | 17 import re |
18 import subprocess | 18 import subprocess |
19 import sys | 19 import sys |
20 | 20 |
21 import devil_chromium | 21 import devil_chromium |
22 | 22 |
23 from devil.android import device_blacklist | 23 from devil.android import device_blacklist |
24 from devil.android import device_errors | 24 from devil.android import device_errors |
25 from devil.android import device_utils | 25 from devil.android import device_utils |
26 from devil.utils import run_tests_helper | 26 from devil.utils import run_tests_helper |
27 from pylib import constants | 27 from pylib import constants |
28 | 28 |
29 sys.path.insert(0, os.path.abspath(os.path.join( | |
30 constants.DIR_SOURCE_ROOT, 'tools', 'swarming_client'))) | |
31 from libs.logdog import bootstrap # pylint: disable=import-error | |
32 | |
33 | 29 |
34 _TZ_UTC = {'TZ': 'UTC'} | 30 _TZ_UTC = {'TZ': 'UTC'} |
35 | 31 |
36 | 32 |
37 def _ListTombstones(device): | 33 def _ListTombstones(device): |
38 """List the tombstone files on the device. | 34 """List the tombstone files on the device. |
39 | 35 |
40 Args: | 36 Args: |
41 device: An instance of DeviceUtils. | 37 device: An instance of DeviceUtils. |
42 | 38 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 Returns: | 247 Returns: |
252 A list of resolved tombstones. | 248 A list of resolved tombstones. |
253 """ | 249 """ |
254 return _ResolveTombstones(jobs, | 250 return _ResolveTombstones(jobs, |
255 _GetTombstonesForDevice(device, | 251 _GetTombstonesForDevice(device, |
256 resolve_all_tombstones, | 252 resolve_all_tombstones, |
257 include_stack_symbols, | 253 include_stack_symbols, |
258 wipe_tombstones)) | 254 wipe_tombstones)) |
259 | 255 |
260 | 256 |
261 def LogdogTombstones(resolved_tombstones, stream_name): | |
262 """Save resolved tombstones to logdog and return the url. | |
263 | |
264 Args: | |
265 stream_name: The name of the logdog stream that records tombstones. | |
266 resolved_tombstones: Resolved tombstones (output of ResolveTombstones). | |
267 | |
268 Returns: | |
269 A url link to the recorded tombstones. | |
270 """ | |
271 try: | |
272 tombstones_url = '' | |
273 stream_client = bootstrap.ButlerBootstrap.probe().stream_client() | |
274 with stream_client.text(stream_name) as logdog_stream: | |
275 for tombstones_line in resolved_tombstones: | |
276 logdog_stream.write(tombstones_line + '\n') | |
277 tombstones_url = logdog_stream.get_viewer_url(stream_name) | |
278 except bootstrap.NotBootstrappedError: | |
279 logging.exception('Error not bootstrapped. Failed to start logdog') | |
280 except (KeyError, ValueError) as e: | |
281 logging.exception('Error when creating stream_client/stream: %s.', e) | |
282 except Exception as e: # pylint: disable=broad-except | |
283 logging.exception('Unknown Error: %s.', e) | |
284 return tombstones_url | |
285 | |
286 | |
287 def main(): | 257 def main(): |
288 custom_handler = logging.StreamHandler(sys.stdout) | 258 custom_handler = logging.StreamHandler(sys.stdout) |
289 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) | 259 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) |
290 logging.getLogger().addHandler(custom_handler) | 260 logging.getLogger().addHandler(custom_handler) |
291 logging.getLogger().setLevel(logging.INFO) | 261 logging.getLogger().setLevel(logging.INFO) |
292 | 262 |
293 parser = argparse.ArgumentParser() | 263 parser = argparse.ArgumentParser() |
294 parser.add_argument('--device', | 264 parser.add_argument('--device', |
295 help='The serial number of the device. If not specified ' | 265 help='The serial number of the device. If not specified ' |
296 'will use all devices.') | 266 'will use all devices.') |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 for device in devices: | 304 for device in devices: |
335 resolved_tombstones = ResolveTombstones( | 305 resolved_tombstones = ResolveTombstones( |
336 device, args.all_tombstones, | 306 device, args.all_tombstones, |
337 args.stack, args.wipe_tombstones, args.jobs) | 307 args.stack, args.wipe_tombstones, args.jobs) |
338 for line in resolved_tombstones: | 308 for line in resolved_tombstones: |
339 logging.info(line) | 309 logging.info(line) |
340 | 310 |
341 | 311 |
342 if __name__ == '__main__': | 312 if __name__ == '__main__': |
343 sys.exit(main()) | 313 sys.exit(main()) |
OLD | NEW |