| 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 |