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

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

Issue 2974163002: Fix the stack script issue when symbolizing tombstones. (Closed)
Patch Set: address John's comments Created 3 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 unified diff | Download patch
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 15 import multiprocessing
16 import os 16 import os
17 import re
18 import subprocess
19 import sys 17 import sys
20 18
21 import devil_chromium 19 import devil_chromium
22 20
23 from devil.android import device_blacklist 21 from devil.android import device_blacklist
24 from devil.android import device_errors 22 from devil.android import device_errors
25 from devil.android import device_utils 23 from devil.android import device_utils
26 from devil.utils import run_tests_helper 24 from devil.utils import run_tests_helper
27 from pylib import constants 25 from pylib import constants
26 from pylib.utils import symbolizer
28 27
29 28
30 _TZ_UTC = {'TZ': 'UTC'} 29 _TZ_UTC = {'TZ': 'UTC'}
31 30
32 31
33 def _ListTombstones(device): 32 def _ListTombstones(device):
34 """List the tombstone files on the device. 33 """List the tombstone files on the device.
35 34
36 Args: 35 Args:
37 device: An instance of DeviceUtils. 36 device: An instance of DeviceUtils.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 88
90 Args: 89 Args:
91 device: An instance of DeviceUtils. 90 device: An instance of DeviceUtils.
92 tombstone_file: the tombstone to delete. 91 tombstone_file: the tombstone to delete.
93 """ 92 """
94 return device.RunShellCommand( 93 return device.RunShellCommand(
95 ['rm', '/data/tombstones/' + tombstone_file], 94 ['rm', '/data/tombstones/' + tombstone_file],
96 as_root=True, check_return=True) 95 as_root=True, check_return=True)
97 96
98 97
99 def _DeviceAbiToArch(device_abi): 98 def _ResolveTombstone(args):
100 # The order of this list is significant to find the more specific match (e.g., 99 tombstone = args[0]
101 # arm64) before the less specific (e.g., arm). 100 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 = [] 101 lines = []
145 lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) + 102 lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) +
146 ', about this long ago: ' + 103 ', about this long ago: ' +
147 (str(tombstone['device_now'] - tombstone['time']) + 104 (str(tombstone['device_now'] - tombstone['time']) +
148 ' Device: ' + tombstone['serial'])] 105 ' Device: ' + tombstone['serial'])]
149 logging.info('\n'.join(lines)) 106 logging.info('\n'.join(lines))
150 logging.info('Resolving...') 107 logging.info('Resolving...')
151 lines += _ResolveSymbols(tombstone['data'], tombstone['stack'], 108 lines += tombstone_symbolizer.ResolveSymbols(
152 tombstone['device_abi']) 109 tombstone['data'],
110 tombstone['device_abi'],
111 tombstone['stack'])
153 return lines 112 return lines
154 113
155 114
156 def _ResolveTombstones(jobs, tombstones): 115 def _ResolveTombstones(jobs, tombstones, tombstone_symbolizer):
157 """Resolve a list of tombstones. 116 """Resolve a list of tombstones.
158 117
159 Args: 118 Args:
160 jobs: the number of jobs to use with multiprocess. 119 jobs: the number of jobs to use with multiprocess.
161 tombstones: a list of tombstones. 120 tombstones: a list of tombstones.
162 """ 121 """
163 if not tombstones: 122 if not tombstones:
164 logging.warning('No tombstones to resolve.') 123 logging.warning('No tombstones to resolve.')
165 return [] 124 return []
125 if (not tombstone_symbolizer.has_unzipped and
jbudorick 2017/07/21 13:46:24 As mentioned in symbolizer, this check should be d
BigBossZhiling 2017/07/21 18:38:14 Done.
126 tombstone_symbolizer.enable_relocation_packing and
127 tombstone_symbolizer.apk_under_test):
128 tombstone_symbolizer.UnzipAPK()
166 if len(tombstones) == 1: 129 if len(tombstones) == 1:
167 data = [_ResolveTombstone(tombstones[0])] 130 data = [_ResolveTombstone([tombstones[0], tombstone_symbolizer])]
168 else: 131 else:
169 pool = multiprocessing.Pool(processes=jobs) 132 pool = multiprocessing.Pool(processes=jobs)
170 data = pool.map(_ResolveTombstone, tombstones) 133 data = pool.map(
134 _ResolveTombstone,
135 [[tombstone, tombstone_symbolizer] for tombstone in tombstones])
171 resolved_tombstones = [] 136 resolved_tombstones = []
172 for tombstone in data: 137 for tombstone in data:
173 resolved_tombstones.extend(tombstone) 138 resolved_tombstones.extend(tombstone)
174 return resolved_tombstones 139 return resolved_tombstones
175 140
176 141
177 def _GetTombstonesForDevice(device, resolve_all_tombstones, 142 def _GetTombstonesForDevice(device, resolve_all_tombstones,
178 include_stack_symbols, 143 include_stack_symbols,
179 wipe_tombstones): 144 wipe_tombstones):
180 """Returns a list of tombstones on a given device. 145 """Returns a list of tombstones on a given device.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 """ 194 """
230 all_tombstones = list(_ListTombstones(device)) 195 all_tombstones = list(_ListTombstones(device))
231 if not all_tombstones: 196 if not all_tombstones:
232 logging.warning('No tombstones to clear.') 197 logging.warning('No tombstones to clear.')
233 198
234 for tombstone_file, _ in all_tombstones: 199 for tombstone_file, _ in all_tombstones:
235 _EraseTombstone(device, tombstone_file) 200 _EraseTombstone(device, tombstone_file)
236 201
237 202
238 def ResolveTombstones(device, resolve_all_tombstones, include_stack_symbols, 203 def ResolveTombstones(device, resolve_all_tombstones, include_stack_symbols,
239 wipe_tombstones, jobs=4): 204 wipe_tombstones, jobs=4,
205 apk_under_test=None, enable_relocation_packing=None,
206 tombstone_symbolizer=None):
240 """Resolve tombstones in the device. 207 """Resolve tombstones in the device.
241 208
242 Args: 209 Args:
243 device: An instance of DeviceUtils. 210 device: An instance of DeviceUtils.
244 resolve_all_tombstone: Whether to resolve every tombstone. 211 resolve_all_tombstone: Whether to resolve every tombstone.
245 include_stack_symbols: Whether to include symbols for stack data. 212 include_stack_symbols: Whether to include symbols for stack data.
246 wipe_tombstones: Whether to wipe tombstones. 213 wipe_tombstones: Whether to wipe tombstones.
247 jobs: Number of jobs to use when processing multiple crash stacks. 214 jobs: Number of jobs to use when processing multiple crash stacks.
248 215
249 Returns: 216 Returns:
250 A list of resolved tombstones. 217 A list of resolved tombstones.
251 """ 218 """
252 return _ResolveTombstones(jobs, 219 return _ResolveTombstones(jobs,
253 _GetTombstonesForDevice(device, 220 _GetTombstonesForDevice(device,
254 resolve_all_tombstones, 221 resolve_all_tombstones,
255 include_stack_symbols, 222 include_stack_symbols,
256 wipe_tombstones)) 223 wipe_tombstones),
224 (tombstone_symbolizer or
jbudorick 2017/07/21 13:46:23 nit: move 'or' down onto the next line
BigBossZhiling 2017/07/21 18:38:14 Done.
225 symbolizer.Symbolizer(
226 apk_under_test,
227 enable_relocation_packing)))
257 228
258 229
259 def main(): 230 def main():
260 custom_handler = logging.StreamHandler(sys.stdout) 231 custom_handler = logging.StreamHandler(sys.stdout)
261 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) 232 custom_handler.setFormatter(run_tests_helper.CustomFormatter())
262 logging.getLogger().addHandler(custom_handler) 233 logging.getLogger().addHandler(custom_handler)
263 logging.getLogger().setLevel(logging.INFO) 234 logging.getLogger().setLevel(logging.INFO)
264 235
265 parser = argparse.ArgumentParser() 236 parser = argparse.ArgumentParser()
266 parser.add_argument('--device', 237 parser.add_argument('--device',
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 for device in devices: 277 for device in devices:
307 resolved_tombstones = ResolveTombstones( 278 resolved_tombstones = ResolveTombstones(
308 device, args.all_tombstones, 279 device, args.all_tombstones,
309 args.stack, args.wipe_tombstones, args.jobs) 280 args.stack, args.wipe_tombstones, args.jobs)
310 for line in resolved_tombstones: 281 for line in resolved_tombstones:
311 logging.info(line) 282 logging.info(line)
312 283
313 284
314 if __name__ == '__main__': 285 if __name__ == '__main__':
315 sys.exit(main()) 286 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698