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

Side by Side Diff: build/android/tombstones.py

Issue 2974163002: Fix the stack script issue when symbolizing tombstones. (Closed)
Patch Set: add todo and crbug; revert changes for intentional crash test case Created 3 years, 4 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 unified diff | Download patch
« no previous file with comments | « build/android/test_runner.pydeps ('k') | build/config/android/internal_rules.gni » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
16 import os 15 import os
17 import re
18 import subprocess
19 import sys 16 import sys
20 17
18 from multiprocessing.pool import ThreadPool
19
21 import devil_chromium 20 import devil_chromium
22 21
23 from devil.android import device_blacklist 22 from devil.android import device_blacklist
24 from devil.android import device_errors 23 from devil.android import device_errors
25 from devil.android import device_utils 24 from devil.android import device_utils
26 from devil.utils import run_tests_helper 25 from devil.utils import run_tests_helper
27 from pylib import constants 26 from pylib import constants
27 from pylib.symbols import stack_symbolizer
28 28
29 29
30 _TZ_UTC = {'TZ': 'UTC'} 30 _TZ_UTC = {'TZ': 'UTC'}
31 31
32 32
33 def _ListTombstones(device): 33 def _ListTombstones(device):
34 """List the tombstone files on the device. 34 """List the tombstone files on the device.
35 35
36 Args: 36 Args:
37 device: An instance of DeviceUtils. 37 device: An instance of DeviceUtils.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 89
90 Args: 90 Args:
91 device: An instance of DeviceUtils. 91 device: An instance of DeviceUtils.
92 tombstone_file: the tombstone to delete. 92 tombstone_file: the tombstone to delete.
93 """ 93 """
94 return device.RunShellCommand( 94 return device.RunShellCommand(
95 ['rm', '/data/tombstones/' + tombstone_file], 95 ['rm', '/data/tombstones/' + tombstone_file],
96 as_root=True, check_return=True) 96 as_root=True, check_return=True)
97 97
98 98
99 def _DeviceAbiToArch(device_abi): 99 def _ResolveTombstone(args):
100 # The order of this list is significant to find the more specific match (e.g., 100 tombstone = args[0]
101 # arm64) before the less specific (e.g., arm). 101 tombstone_symbolizer = args[1]
102 arches = ['arm64', 'arm', 'x86_64', 'x86_64', 'x86', 'mips']
103 for arch in arches:
104 if arch in device_abi:
105 return arch
106 raise RuntimeError('Unknown device ABI: %s' % device_abi)
107
108
109 def _ResolveSymbols(tombstone_data, include_stack, device_abi):
110 """Run the stack tool for given tombstone input.
111
112 Args:
113 tombstone_data: a list of strings of tombstone data.
114 include_stack: boolean whether to include stack data in output.
115 device_abi: the default ABI of the device which generated the tombstone.
116
117 Yields:
118 A string for each line of resolved stack output.
119 """
120 # Check if the tombstone data has an ABI listed, if so use this in preference
121 # to the device's default ABI.
122 for line in tombstone_data:
123 found_abi = re.search('ABI: \'(.+?)\'', line)
124 if found_abi:
125 device_abi = found_abi.group(1)
126 arch = _DeviceAbiToArch(device_abi)
127 if not arch:
128 return
129
130 stack_tool = os.path.join(os.path.dirname(__file__), '..', '..',
131 'third_party', 'android_platform', 'development',
132 'scripts', 'stack')
133 cmd = [stack_tool, '--arch', arch, '--output-directory',
134 constants.GetOutDirectory()]
135 proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
136 output = proc.communicate(input='\n'.join(tombstone_data))[0]
137 for line in output.split('\n'):
138 if not include_stack and 'Stack Data:' in line:
139 break
140 yield line
141
142
143 def _ResolveTombstone(tombstone):
144 lines = [] 102 lines = []
145 lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) + 103 lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) +
146 ', about this long ago: ' + 104 ', about this long ago: ' +
147 (str(tombstone['device_now'] - tombstone['time']) + 105 (str(tombstone['device_now'] - tombstone['time']) +
148 ' Device: ' + tombstone['serial'])] 106 ' Device: ' + tombstone['serial'])]
149 logging.info('\n'.join(lines)) 107 logging.info('\n'.join(lines))
150 logging.info('Resolving...') 108 logging.info('Resolving...')
151 lines += _ResolveSymbols(tombstone['data'], tombstone['stack'], 109 lines += tombstone_symbolizer.ExtractAndResolveNativeStackTraces(
152 tombstone['device_abi']) 110 tombstone['data'],
111 tombstone['device_abi'],
112 tombstone['stack'])
153 return lines 113 return lines
154 114
155 115
156 def _ResolveTombstones(jobs, tombstones): 116 def _ResolveTombstones(jobs, tombstones, tombstone_symbolizer):
157 """Resolve a list of tombstones. 117 """Resolve a list of tombstones.
158 118
159 Args: 119 Args:
160 jobs: the number of jobs to use with multiprocess. 120 jobs: the number of jobs to use with multithread.
161 tombstones: a list of tombstones. 121 tombstones: a list of tombstones.
162 """ 122 """
163 if not tombstones: 123 if not tombstones:
164 logging.warning('No tombstones to resolve.') 124 logging.warning('No tombstones to resolve.')
165 return [] 125 return []
126 tombstone_symbolizer.UnzipAPKIfNecessary()
166 if len(tombstones) == 1: 127 if len(tombstones) == 1:
167 data = [_ResolveTombstone(tombstones[0])] 128 data = [_ResolveTombstone([tombstones[0], tombstone_symbolizer])]
168 else: 129 else:
169 pool = multiprocessing.Pool(processes=jobs) 130 pool = ThreadPool(jobs)
170 data = pool.map(_ResolveTombstone, tombstones) 131 data = pool.map(
132 _ResolveTombstone,
133 [[tombstone, tombstone_symbolizer] for tombstone in tombstones])
171 resolved_tombstones = [] 134 resolved_tombstones = []
172 for tombstone in data: 135 for tombstone in data:
173 resolved_tombstones.extend(tombstone) 136 resolved_tombstones.extend(tombstone)
174 return resolved_tombstones 137 return resolved_tombstones
175 138
176 139
177 def _GetTombstonesForDevice(device, resolve_all_tombstones, 140 def _GetTombstonesForDevice(device, resolve_all_tombstones,
178 include_stack_symbols, 141 include_stack_symbols,
179 wipe_tombstones): 142 wipe_tombstones):
180 """Returns a list of tombstones on a given device. 143 """Returns a list of tombstones on a given device.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 """ 192 """
230 all_tombstones = list(_ListTombstones(device)) 193 all_tombstones = list(_ListTombstones(device))
231 if not all_tombstones: 194 if not all_tombstones:
232 logging.warning('No tombstones to clear.') 195 logging.warning('No tombstones to clear.')
233 196
234 for tombstone_file, _ in all_tombstones: 197 for tombstone_file, _ in all_tombstones:
235 _EraseTombstone(device, tombstone_file) 198 _EraseTombstone(device, tombstone_file)
236 199
237 200
238 def ResolveTombstones(device, resolve_all_tombstones, include_stack_symbols, 201 def ResolveTombstones(device, resolve_all_tombstones, include_stack_symbols,
239 wipe_tombstones, jobs=4): 202 wipe_tombstones, jobs=4,
203 apk_under_test=None, enable_relocation_packing=None,
204 tombstone_symbolizer=None):
240 """Resolve tombstones in the device. 205 """Resolve tombstones in the device.
241 206
242 Args: 207 Args:
243 device: An instance of DeviceUtils. 208 device: An instance of DeviceUtils.
244 resolve_all_tombstone: Whether to resolve every tombstone. 209 resolve_all_tombstone: Whether to resolve every tombstone.
245 include_stack_symbols: Whether to include symbols for stack data. 210 include_stack_symbols: Whether to include symbols for stack data.
246 wipe_tombstones: Whether to wipe tombstones. 211 wipe_tombstones: Whether to wipe tombstones.
247 jobs: Number of jobs to use when processing multiple crash stacks. 212 jobs: Number of jobs to use when processing multiple crash stacks.
248 213
249 Returns: 214 Returns:
250 A list of resolved tombstones. 215 A list of resolved tombstones.
251 """ 216 """
252 return _ResolveTombstones(jobs, 217 return _ResolveTombstones(jobs,
253 _GetTombstonesForDevice(device, 218 _GetTombstonesForDevice(device,
254 resolve_all_tombstones, 219 resolve_all_tombstones,
255 include_stack_symbols, 220 include_stack_symbols,
256 wipe_tombstones)) 221 wipe_tombstones),
222 (tombstone_symbolizer
223 or stack_symbolizer.Symbolizer(
224 apk_under_test,
225 enable_relocation_packing)))
257 226
258 227
259 def main(): 228 def main():
260 custom_handler = logging.StreamHandler(sys.stdout) 229 custom_handler = logging.StreamHandler(sys.stdout)
261 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) 230 custom_handler.setFormatter(run_tests_helper.CustomFormatter())
262 logging.getLogger().addHandler(custom_handler) 231 logging.getLogger().addHandler(custom_handler)
263 logging.getLogger().setLevel(logging.INFO) 232 logging.getLogger().setLevel(logging.INFO)
264 233
265 parser = argparse.ArgumentParser() 234 parser = argparse.ArgumentParser()
266 parser.add_argument('--device', 235 parser.add_argument('--device',
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 for device in devices: 275 for device in devices:
307 resolved_tombstones = ResolveTombstones( 276 resolved_tombstones = ResolveTombstones(
308 device, args.all_tombstones, 277 device, args.all_tombstones,
309 args.stack, args.wipe_tombstones, args.jobs) 278 args.stack, args.wipe_tombstones, args.jobs)
310 for line in resolved_tombstones: 279 for line in resolved_tombstones:
311 logging.info(line) 280 logging.info(line)
312 281
313 282
314 if __name__ == '__main__': 283 if __name__ == '__main__':
315 sys.exit(main()) 284 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/test_runner.pydeps ('k') | build/config/android/internal_rules.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698