| 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. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 """Deletes a tombstone from the device. | 69 """Deletes a tombstone from the device. |
| 70 | 70 |
| 71 Args: | 71 Args: |
| 72 device: An instance of DeviceUtils. | 72 device: An instance of DeviceUtils. |
| 73 tombstone_file: the tombstone to delete. | 73 tombstone_file: the tombstone to delete. |
| 74 """ | 74 """ |
| 75 return device.RunShellCommand( | 75 return device.RunShellCommand( |
| 76 'rm /data/tombstones/' + tombstone_file, as_root=True) | 76 'rm /data/tombstones/' + tombstone_file, as_root=True) |
| 77 | 77 |
| 78 | 78 |
| 79 def _ResolveSymbols(tombstone_data, include_stack): | 79 def _ResolveSymbols(tombstone_data, include_stack, arch): |
| 80 """Run the stack tool for given tombstone input. | 80 """Run the stack tool for given tombstone input. |
| 81 | 81 |
| 82 Args: | 82 Args: |
| 83 tombstone_data: a list of strings of tombstone data. | 83 tombstone_data: a list of strings of tombstone data. |
| 84 include_stack: boolean whether to include stack data in output. | 84 include_stack: boolean whether to include stack data in output. |
| 85 arch: the device architecture of tombstone data. |
| 85 | 86 |
| 86 Yields: | 87 Yields: |
| 87 A string for each line of resolved stack output. | 88 A string for each line of resolved stack output. |
| 88 """ | 89 """ |
| 89 stack_tool = os.path.join(os.path.dirname(__file__), '..', '..', | 90 stack_tool = os.path.join(os.path.dirname(__file__), '..', '..', |
| 90 'third_party', 'android_platform', 'development', | 91 'third_party', 'android_platform', 'development', |
| 91 'scripts', 'stack') | 92 'scripts', 'stack') |
| 92 proc = subprocess.Popen(stack_tool, stdin=subprocess.PIPE, | 93 proc = subprocess.Popen([stack_tool, '--arch', arch], stdin=subprocess.PIPE, |
| 93 stdout=subprocess.PIPE) | 94 stdout=subprocess.PIPE) |
| 94 output = proc.communicate(input='\n'.join(tombstone_data))[0] | 95 output = proc.communicate(input='\n'.join(tombstone_data))[0] |
| 95 for line in output.split('\n'): | 96 for line in output.split('\n'): |
| 96 if not include_stack and 'Stack Data:' in line: | 97 if not include_stack and 'Stack Data:' in line: |
| 97 break | 98 break |
| 98 yield line | 99 yield line |
| 99 | 100 |
| 100 | 101 |
| 101 def _ResolveTombstone(tombstone): | 102 def _ResolveTombstone(tombstone): |
| 102 lines = [] | 103 lines = [] |
| 103 lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) + | 104 lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) + |
| 104 ', about this long ago: ' + | 105 ', about this long ago: ' + |
| 105 (str(tombstone['device_now'] - tombstone['time']) + | 106 (str(tombstone['device_now'] - tombstone['time']) + |
| 106 ' Device: ' + tombstone['serial'])] | 107 ' Device: ' + tombstone['serial'])] |
| 107 print '\n'.join(lines) | 108 print '\n'.join(lines) |
| 108 print 'Resolving...' | 109 print 'Resolving...' |
| 109 lines += _ResolveSymbols(tombstone['data'], tombstone['stack']) | 110 lines += _ResolveSymbols(tombstone['data'], tombstone['stack'], |
| 111 tombstone['arch']) |
| 110 return lines | 112 return lines |
| 111 | 113 |
| 112 | 114 |
| 113 def _ResolveTombstones(jobs, tombstones): | 115 def _ResolveTombstones(jobs, tombstones): |
| 114 """Resolve a list of tombstones. | 116 """Resolve a list of tombstones. |
| 115 | 117 |
| 116 Args: | 118 Args: |
| 117 jobs: the number of jobs to use with multiprocess. | 119 jobs: the number of jobs to use with multiprocess. |
| 118 tombstones: a list of tombstones. | 120 tombstones: a list of tombstones. |
| 119 """ | 121 """ |
| (...skipping 24 matching lines...) Expand all Loading... |
| 144 | 146 |
| 145 # Sort the tombstones in date order, descending | 147 # Sort the tombstones in date order, descending |
| 146 all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1])) | 148 all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1])) |
| 147 | 149 |
| 148 # Only resolve the most recent unless --all-tombstones given. | 150 # Only resolve the most recent unless --all-tombstones given. |
| 149 tombstones = all_tombstones if options.all_tombstones else [all_tombstones[0]] | 151 tombstones = all_tombstones if options.all_tombstones else [all_tombstones[0]] |
| 150 | 152 |
| 151 device_now = _GetDeviceDateTime(device) | 153 device_now = _GetDeviceDateTime(device) |
| 152 for tombstone_file, tombstone_time in tombstones: | 154 for tombstone_file, tombstone_time in tombstones: |
| 153 ret += [{'serial': str(device), | 155 ret += [{'serial': str(device), |
| 156 'arch': device.GetProp('ro.product.cpu.abi'), |
| 154 'device_now': device_now, | 157 'device_now': device_now, |
| 155 'time': tombstone_time, | 158 'time': tombstone_time, |
| 156 'file': tombstone_file, | 159 'file': tombstone_file, |
| 157 'stack': options.stack, | 160 'stack': options.stack, |
| 158 'data': _GetTombstoneData(device, tombstone_file)}] | 161 'data': _GetTombstoneData(device, tombstone_file)}] |
| 159 | 162 |
| 160 # Erase all the tombstones if desired. | 163 # Erase all the tombstones if desired. |
| 161 if options.wipe_tombstones: | 164 if options.wipe_tombstones: |
| 162 for tombstone_file, _ in all_tombstones: | 165 for tombstone_file, _ in all_tombstones: |
| 163 _EraseTombstone(device, tombstone_file) | 166 _EraseTombstone(device, tombstone_file) |
| 164 | 167 |
| 165 return ret | 168 return ret |
| 166 | 169 |
| 170 |
| 167 def main(): | 171 def main(): |
| 168 parser = optparse.OptionParser() | 172 parser = optparse.OptionParser() |
| 169 parser.add_option('--device', | 173 parser.add_option('--device', |
| 170 help='The serial number of the device. If not specified ' | 174 help='The serial number of the device. If not specified ' |
| 171 'will use all devices.') | 175 'will use all devices.') |
| 172 parser.add_option('-a', '--all-tombstones', action='store_true', | 176 parser.add_option('-a', '--all-tombstones', action='store_true', |
| 173 help="""Resolve symbols for all tombstones, rather than just | 177 help="""Resolve symbols for all tombstones, rather than just |
| 174 the most recent""") | 178 the most recent""") |
| 175 parser.add_option('-s', '--stack', action='store_true', | 179 parser.add_option('-s', '--stack', action='store_true', |
| 176 help='Also include symbols for stack data') | 180 help='Also include symbols for stack data') |
| (...skipping 12 matching lines...) Expand all Loading... |
| 189 | 193 |
| 190 tombstones = [] | 194 tombstones = [] |
| 191 for device_serial in devices: | 195 for device_serial in devices: |
| 192 device = device_utils.DeviceUtils(device_serial) | 196 device = device_utils.DeviceUtils(device_serial) |
| 193 tombstones += _GetTombstonesForDevice(device, options) | 197 tombstones += _GetTombstonesForDevice(device, options) |
| 194 | 198 |
| 195 _ResolveTombstones(options.jobs, tombstones) | 199 _ResolveTombstones(options.jobs, tombstones) |
| 196 | 200 |
| 197 if __name__ == '__main__': | 201 if __name__ == '__main__': |
| 198 sys.exit(main()) | 202 sys.exit(main()) |
| OLD | NEW |