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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 if len(tombstones) == 1: | 163 if len(tombstones) == 1: |
164 data = [_ResolveTombstone(tombstones[0])] | 164 data = [_ResolveTombstone(tombstones[0])] |
165 else: | 165 else: |
166 pool = multiprocessing.Pool(processes=jobs) | 166 pool = multiprocessing.Pool(processes=jobs) |
167 data = pool.map(_ResolveTombstone, tombstones) | 167 data = pool.map(_ResolveTombstone, tombstones) |
168 for tombstone in data: | 168 for tombstone in data: |
169 for line in tombstone: | 169 for line in tombstone: |
170 logging.info(line) | 170 logging.info(line) |
171 | 171 |
172 | 172 |
173 def _GetTombstonesForDevice(device, args): | 173 def _GetTombstonesForDevice(device, every_tombstone, stack, wipe_tombstones): |
174 """Returns a list of tombstones on a given device. | 174 """Returns a list of tombstones on a given device. |
175 | 175 |
176 Args: | 176 Args: |
177 device: An instance of DeviceUtils. | 177 device: An instance of DeviceUtils. |
178 args: command line arguments | 178 every_tombstone: Whether to resolve every tombstone. |
mikecase (-- gone --)
2016/08/01 22:44:30
Maybe rename to resolve_all_tombstones.
Its awkwa
BigBossZhiling
2016/08/01 23:04:35
Done.
| |
179 stack: Stack. | |
mikecase (-- gone --)
2016/08/01 22:44:30
Probably at least write the datatype for the stack
BigBossZhiling
2016/08/01 23:04:35
I think it is boolean. But I don't know what this
| |
180 wipe_tombstones: Whether to wipe tombstones. | |
179 """ | 181 """ |
180 ret = [] | 182 ret = [] |
181 all_tombstones = list(_ListTombstones(device)) | 183 all_tombstones = list(_ListTombstones(device)) |
182 if not all_tombstones: | 184 if not all_tombstones: |
183 logging.warning('No tombstones.') | 185 logging.warning('No tombstones.') |
184 return ret | 186 return ret |
185 | 187 |
186 # Sort the tombstones in date order, descending | 188 # Sort the tombstones in date order, descending |
187 all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1])) | 189 all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1])) |
188 | 190 |
189 # Only resolve the most recent unless --all-tombstones given. | 191 # Only resolve the most recent unless --all-tombstones given. |
190 tombstones = all_tombstones if args.all_tombstones else [all_tombstones[0]] | 192 tombstones = all_tombstones if every_tombstone else [all_tombstones[0]] |
191 | 193 |
192 device_now = _GetDeviceDateTime(device) | 194 device_now = _GetDeviceDateTime(device) |
193 try: | 195 try: |
194 for tombstone_file, tombstone_time in tombstones: | 196 for tombstone_file, tombstone_time in tombstones: |
195 ret += [{'serial': str(device), | 197 ret += [{'serial': str(device), |
196 'device_abi': device.product_cpu_abi, | 198 'device_abi': device.product_cpu_abi, |
197 'device_now': device_now, | 199 'device_now': device_now, |
198 'time': tombstone_time, | 200 'time': tombstone_time, |
199 'file': tombstone_file, | 201 'file': tombstone_file, |
200 'stack': args.stack, | 202 'stack': stack, |
201 'data': _GetTombstoneData(device, tombstone_file)}] | 203 'data': _GetTombstoneData(device, tombstone_file)}] |
202 except device_errors.CommandFailedError: | 204 except device_errors.CommandFailedError: |
203 for entry in device.StatDirectory( | 205 for entry in device.StatDirectory( |
204 '/data/tombstones', as_root=True, timeout=60): | 206 '/data/tombstones', as_root=True, timeout=60): |
205 logging.info('%s: %s', str(device), entry) | 207 logging.info('%s: %s', str(device), entry) |
206 raise | 208 raise |
207 | 209 |
208 # Erase all the tombstones if desired. | 210 # Erase all the tombstones if desired. |
209 if args.wipe_tombstones: | 211 if wipe_tombstones: |
210 for tombstone_file, _ in all_tombstones: | 212 for tombstone_file, _ in all_tombstones: |
211 _EraseTombstone(device, tombstone_file) | 213 _EraseTombstone(device, tombstone_file) |
212 | 214 |
213 return ret | 215 return ret |
214 | 216 |
217 def ClearAllTombstones(device): | |
218 """Clear all tombstones in the device. | |
219 | |
220 Args: | |
221 device: An instance of DeviceUtils. | |
222 """ | |
223 all_tombstones = list(_ListTombstones(device)) | |
224 if not all_tombstones: | |
225 logging.warning('No tombstones.') | |
mikecase (-- gone --)
2016/08/01 22:44:30
Maybe slightly more descriptive warning. Like "No
BigBossZhiling
2016/08/01 23:04:35
Done.
| |
226 | |
227 for tombstone_file, _ in all_tombstones: | |
228 _EraseTombstone(device, tombstone_file) | |
229 | |
230 def ResolveAllTombstones(device, all_tombstones, stack, wipe_tombstones, | |
231 jobs=4): | |
232 return _ResolveTombstones(jobs, | |
233 _GetTombstonesForDevice(device, | |
234 all_tombstones, | |
235 stack, wipe_tombstones)) | |
215 | 236 |
216 def main(): | 237 def main(): |
217 custom_handler = logging.StreamHandler(sys.stdout) | 238 custom_handler = logging.StreamHandler(sys.stdout) |
218 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) | 239 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) |
219 logging.getLogger().addHandler(custom_handler) | 240 logging.getLogger().addHandler(custom_handler) |
220 logging.getLogger().setLevel(logging.INFO) | 241 logging.getLogger().setLevel(logging.INFO) |
221 | 242 |
222 parser = argparse.ArgumentParser() | 243 parser = argparse.ArgumentParser() |
223 parser.add_argument('--device', | 244 parser.add_argument('--device', |
224 help='The serial number of the device. If not specified ' | 245 help='The serial number of the device. If not specified ' |
(...skipping 28 matching lines...) Expand all Loading... | |
253 constants.CheckOutputDirectory() | 274 constants.CheckOutputDirectory() |
254 | 275 |
255 if args.device: | 276 if args.device: |
256 devices = [device_utils.DeviceUtils(args.device)] | 277 devices = [device_utils.DeviceUtils(args.device)] |
257 else: | 278 else: |
258 devices = device_utils.DeviceUtils.HealthyDevices(blacklist) | 279 devices = device_utils.DeviceUtils.HealthyDevices(blacklist) |
259 | 280 |
260 # This must be done serially because strptime can hit a race condition if | 281 # This must be done serially because strptime can hit a race condition if |
261 # used for the first time in a multithreaded environment. | 282 # used for the first time in a multithreaded environment. |
262 # http://bugs.python.org/issue7980 | 283 # http://bugs.python.org/issue7980 |
263 tombstones = [] | |
264 for device in devices: | 284 for device in devices: |
265 tombstones += _GetTombstonesForDevice(device, args) | 285 ResolveAllTombstones(device, args.all_tombstones, |
mikecase (-- gone --)
2016/08/01 22:44:30
This indentation looks off.
BigBossZhiling
2016/08/01 23:04:35
Done.
| |
266 | 286 args.stack, args.wipe_tombstones, args.jobs) |
267 _ResolveTombstones(args.jobs, tombstones) | |
268 | |
269 | 287 |
270 if __name__ == '__main__': | 288 if __name__ == '__main__': |
271 sys.exit(main()) | 289 sys.exit(main()) |
OLD | NEW |