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 |