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

Unified Diff: build/android/tombstones.py

Issue 18473004: Android: adds stack symbolization utilities. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/android/tests/symbolize/b.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/tombstones.py
diff --git a/build/android/tombstones.py b/build/android/tombstones.py
new file mode 100755
index 0000000000000000000000000000000000000000..a279c63d3857bb0639e9fa1cfd1861d86f92ddeb
--- /dev/null
+++ b/build/android/tombstones.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Find the most recent tombstone file(s) on all connected devices
+# and prints their stacks.
+#
+# Assumes tombstone file was created with current symbols.
+
+import datetime
+import logging
+import multiprocessing
+import os
+import subprocess
+import sys
+import optparse
+
+from pylib import android_commands
+
+
+def _ListTombstones(adb):
+ """List the tombstone files on the device.
+
+ Args:
+ adb: An instance of AndroidCommands.
+
+ Yields:
+ Tuples of (tombstone filename, date time of file on device).
+ """
+ lines = adb.RunShellCommand('TZ=UTC su -c ls -a -l /data/tombstones')
+ for line in lines:
+ if 'tombstone' in line and not 'No such file or directory' in line:
+ details = line.split()
+ t = datetime.datetime.strptime(details[-3] + ' ' + details[-2],
+ '%Y-%m-%d %H:%M')
+ yield details[-1], t
+
+
+def _GetDeviceDateTime(adb):
+ """Determine the date time on the device.
+
+ Args:
+ adb: An instance of AndroidCommands.
+
+ Returns:
+ A datetime instance.
+ """
+ device_now_string = adb.RunShellCommand('TZ=UTC date')
+ return datetime.datetime.strptime(
+ device_now_string[0], '%a %b %d %H:%M:%S %Z %Y')
+
+
+def _GetTombstoneData(adb, tombstone_file):
+ """Retrieve the tombstone data from the device
+
+ Args:
+ tombstone_file: the tombstone to retrieve
+
+ Returns:
+ A list of lines
+ """
+ return adb.GetProtectedFileContents('/data/tombstones/' + tombstone_file)
+
+
+def _EraseTombstone(adb, tombstone_file):
+ """Deletes a tombstone from the device.
+
+ Args:
+ tombstone_file: the tombstone to delete.
+ """
+ return adb.RunShellCommand('su -c rm /data/tombstones/' + tombstone_file)
+
+
+def _ResolveSymbols(tombstone_data, include_stack):
+ """Run the stack tool for given tombstone input.
+
+ Args:
+ tombstone_data: a list of strings of tombstone data.
+ include_stack: boolean whether to include stack data in output.
+
+ Yields:
+ A string for each line of resolved stack output.
+ """
+ stack_tool = os.path.join(os.path.dirname(__file__), '..', '..',
+ 'third_party', 'android_platform', 'development',
+ 'scripts', 'stack')
+ proc = subprocess.Popen(stack_tool, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ output = proc.communicate(input='\n'.join(tombstone_data))[0]
+ for line in output.split('\n'):
+ if not include_stack and 'Stack Data:' in line:
+ break
+ yield line
+
+
+def _ResolveTombstone(tombstone):
+ lines = []
+ lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) +
+ ', about this long ago: ' +
+ (str(tombstone['device_now'] - tombstone['time']) +
+ ' Device: ' + tombstone['serial'])]
+ print '\n'.join(lines)
+ print 'Resolving...'
+ lines += _ResolveSymbols(tombstone['data'], tombstone['stack'])
+ return lines
+
+
+def _ResolveTombstones(jobs, tombstones):
+ """Resolve a list of tombstones.
+
+ Args:
+ jobs: the number of jobs to use with multiprocess.
+ tombstones: a list of tombstones.
+ """
+ if not tombstones:
+ print 'No device attached? Or no tombstones?'
+ return
+ if len(tombstones) == 1:
+ data = _ResolveTombstone(tombstones[0])
+ else:
+ pool = multiprocessing.Pool(processes=jobs)
+ data = pool.map(_ResolveTombstone, tombstones)
+ data = ['\n'.join(d) for d in data]
+ print '\n'.join(data)
+
+
+def _GetTombstonesForDevice(adb, options):
+ """Returns a list of tombstones on a given adb connection.
+
+ Args:
+ adb: An instance of Androidcommands.
+ options: command line arguments from OptParse
+ """
+ ret = []
+ all_tombstones = list(_ListTombstones(adb))
+ if not all_tombstones:
+ print 'No device attached? Or no tombstones?'
+ return ret
+
+ # Sort the tombstones in date order, descending
+ all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1]))
+
+ # Only resolve the most recent unless --all-tombstones given.
+ tombstones = all_tombstones if options.all_tombstones else [all_tombstones[0]]
+
+ device_now = _GetDeviceDateTime(adb)
+ for tombstone_file, tombstone_time in tombstones:
+ ret += [{'serial': adb.Adb().GetSerialNumber(),
+ 'device_now': device_now,
+ 'time': tombstone_time,
+ 'file': tombstone_file,
+ 'stack': options.stack,
+ 'data': _GetTombstoneData(adb, tombstone_file)}]
+
+ # Erase all the tombstones if desired.
+ if options.wipe_tombstones:
+ for tombstone_file, _ in all_tombstones:
+ _EraseTombstone(adb, tombstone_file)
+
+ return ret
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('-a', '--all-tombstones', action='store_true',
+ dest='all_tombstones', default=False,
+ help="""Resolve symbols for all tombstones, rather than just
+ the most recent""")
+ parser.add_option('-s', '--stack', action='store_true',
+ dest='stack', default=False,
+ help='Also include symbols for stack data')
+ parser.add_option('-w', '--wipe-tombstones', action='store_true',
+ dest='wipe_tombstones', default=False,
+ help='Erase all tombstones from device after processing')
+ parser.add_option('-j', '--jobs', type='int',
+ default=4,
+ help='Number of jobs to use when processing multiple '
+ 'crash stacks.')
+ options, args = parser.parse_args()
+
+ devices = android_commands.GetAttachedDevices()
+ tombstones = []
+ for device in devices:
+ adb = android_commands.AndroidCommands(device)
+ tombstones += _GetTombstonesForDevice(adb, options)
+
+ _ResolveTombstones(options.jobs, tombstones)
+
+if __name__ == '__main__':
+ sys.exit(main())
« no previous file with comments | « build/android/tests/symbolize/b.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698