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

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

Issue 2974163002: Fix the stack script issue when symbolizing tombstones. (Closed)
Patch Set: created symbolizer.py 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'], tombstone['stack'],
110 tombstone['device_abi'])
153 return lines 111 return lines
154 112
155 113
156 def _ResolveTombstones(jobs, tombstones): 114 def _ResolveTombstones(jobs, tombstones, tombstone_symbolizer):
157 """Resolve a list of tombstones. 115 """Resolve a list of tombstones.
158 116
159 Args: 117 Args:
160 jobs: the number of jobs to use with multiprocess. 118 jobs: the number of jobs to use with multiprocess.
161 tombstones: a list of tombstones. 119 tombstones: a list of tombstones.
162 """ 120 """
163 if not tombstones: 121 if not tombstones:
164 logging.warning('No tombstones to resolve.') 122 logging.warning('No tombstones to resolve.')
165 return [] 123 return []
166 if len(tombstones) == 1: 124 if len(tombstones) == 1:
167 data = [_ResolveTombstone(tombstones[0])] 125 data = [_ResolveTombstone([tombstones[0], tombstone_symbolizer])]
168 else: 126 else:
169 pool = multiprocessing.Pool(processes=jobs) 127 pool = multiprocessing.Pool(processes=jobs)
170 data = pool.map(_ResolveTombstone, tombstones) 128 data = pool.map(
jbudorick 2017/07/20 15:58:04 I'm a little concerned about this -- what happens
129 _ResolveTombstone,
130 [[tombstone, tombstone_symbolizer] for tombstone in tombstones])
171 resolved_tombstones = [] 131 resolved_tombstones = []
172 for tombstone in data: 132 for tombstone in data:
173 resolved_tombstones.extend(tombstone) 133 resolved_tombstones.extend(tombstone)
174 return resolved_tombstones 134 return resolved_tombstones
175 135
176 136
177 def _GetTombstonesForDevice(device, resolve_all_tombstones, 137 def _GetTombstonesForDevice(device, resolve_all_tombstones,
178 include_stack_symbols, 138 include_stack_symbols,
179 wipe_tombstones): 139 wipe_tombstones):
180 """Returns a list of tombstones on a given device. 140 """Returns a list of tombstones on a given device.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 """ 189 """
230 all_tombstones = list(_ListTombstones(device)) 190 all_tombstones = list(_ListTombstones(device))
231 if not all_tombstones: 191 if not all_tombstones:
232 logging.warning('No tombstones to clear.') 192 logging.warning('No tombstones to clear.')
233 193
234 for tombstone_file, _ in all_tombstones: 194 for tombstone_file, _ in all_tombstones:
235 _EraseTombstone(device, tombstone_file) 195 _EraseTombstone(device, tombstone_file)
236 196
237 197
238 def ResolveTombstones(device, resolve_all_tombstones, include_stack_symbols, 198 def ResolveTombstones(device, resolve_all_tombstones, include_stack_symbols,
239 wipe_tombstones, jobs=4): 199 wipe_tombstones, jobs=4, packed_libs=None,
200 apk_under_test=None, enable_relocation_packing=None,
201 tombstone_symbolizer=None):
jbudorick 2017/07/20 15:58:04 Not exactly what I had in mind, but I like this to
BigBossZhiling 2017/07/20 23:11:38 Acknowledged.
240 """Resolve tombstones in the device. 202 """Resolve tombstones in the device.
241 203
242 Args: 204 Args:
243 device: An instance of DeviceUtils. 205 device: An instance of DeviceUtils.
244 resolve_all_tombstone: Whether to resolve every tombstone. 206 resolve_all_tombstone: Whether to resolve every tombstone.
245 include_stack_symbols: Whether to include symbols for stack data. 207 include_stack_symbols: Whether to include symbols for stack data.
246 wipe_tombstones: Whether to wipe tombstones. 208 wipe_tombstones: Whether to wipe tombstones.
247 jobs: Number of jobs to use when processing multiple crash stacks. 209 jobs: Number of jobs to use when processing multiple crash stacks.
248 210
249 Returns: 211 Returns:
250 A list of resolved tombstones. 212 A list of resolved tombstones.
251 """ 213 """
252 return _ResolveTombstones(jobs, 214 return _ResolveTombstones(jobs,
253 _GetTombstonesForDevice(device, 215 _GetTombstonesForDevice(device,
254 resolve_all_tombstones, 216 resolve_all_tombstones,
255 include_stack_symbols, 217 include_stack_symbols,
256 wipe_tombstones)) 218 wipe_tombstones),
219 (tombstone_symbolizer or
220 symbolizer.Symbolizer(
221 apk_under_test,
222 enable_relocation_packing,
223 packed_libs)))
257 224
258 225
259 def main(): 226 def main():
260 custom_handler = logging.StreamHandler(sys.stdout) 227 custom_handler = logging.StreamHandler(sys.stdout)
261 custom_handler.setFormatter(run_tests_helper.CustomFormatter()) 228 custom_handler.setFormatter(run_tests_helper.CustomFormatter())
262 logging.getLogger().addHandler(custom_handler) 229 logging.getLogger().addHandler(custom_handler)
263 logging.getLogger().setLevel(logging.INFO) 230 logging.getLogger().setLevel(logging.INFO)
264 231
265 parser = argparse.ArgumentParser() 232 parser = argparse.ArgumentParser()
266 parser.add_argument('--device', 233 parser.add_argument('--device',
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 for device in devices: 273 for device in devices:
307 resolved_tombstones = ResolveTombstones( 274 resolved_tombstones = ResolveTombstones(
308 device, args.all_tombstones, 275 device, args.all_tombstones,
309 args.stack, args.wipe_tombstones, args.jobs) 276 args.stack, args.wipe_tombstones, args.jobs)
310 for line in resolved_tombstones: 277 for line in resolved_tombstones:
311 logging.info(line) 278 logging.info(line)
312 279
313 280
314 if __name__ == '__main__': 281 if __name__ == '__main__':
315 sys.exit(main()) 282 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698