OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (C) 2013 The Android Open Source Project | 3 # Copyright (C) 2013 The Android Open Source Project |
4 # | 4 # |
5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
8 # | 8 # |
9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
10 # | 10 # |
(...skipping 15 matching lines...) Expand all Loading... | |
26 import re | 26 import re |
27 import struct | 27 import struct |
28 import subprocess | 28 import subprocess |
29 import sys | 29 import sys |
30 import zipfile | 30 import zipfile |
31 | 31 |
32 CHROME_SRC = os.path.join(os.path.realpath(os.path.dirname(__file__)), | 32 CHROME_SRC = os.path.join(os.path.realpath(os.path.dirname(__file__)), |
33 os.pardir, os.pardir, os.pardir, os.pardir) | 33 os.pardir, os.pardir, os.pardir, os.pardir) |
34 ANDROID_BUILD_TOP = CHROME_SRC | 34 ANDROID_BUILD_TOP = CHROME_SRC |
35 SYMBOLS_DIR = CHROME_SRC | 35 SYMBOLS_DIR = CHROME_SRC |
36 CHROME_SYMBOLS_DIR = CHROME_SRC | 36 CHROME_SYMBOLS_DIR = None |
37 | 37 |
38 ARCH = "arm" | 38 ARCH = "arm" |
39 | 39 |
40 TOOLCHAIN_INFO = None | 40 TOOLCHAIN_INFO = None |
41 | 41 |
42 sys.path.insert(0, os.path.join(CHROME_SRC, 'build', 'android')) | 42 sys.path.insert(0, os.path.join(CHROME_SRC, 'build', 'android')) |
43 from pylib.symbols import elf_symbolizer | 43 from pylib.symbols import elf_symbolizer |
44 | 44 |
45 # See: | 45 # See: |
46 # http://bugs.python.org/issue14315 | 46 # http://bugs.python.org/issue14315 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 | 195 |
196 Args: | 196 Args: |
197 prefix_list: list of path prefixes. | 197 prefix_list: list of path prefixes. |
198 suffix_list: list of path suffixes. | 198 suffix_list: list of path suffixes. |
199 | 199 |
200 Returns: | 200 Returns: |
201 List of paths each of which joins a prefix with a suffix. | 201 List of paths each of which joins a prefix with a suffix. |
202 """ | 202 """ |
203 return [ | 203 return [ |
204 os.path.join(prefix, suffix) | 204 os.path.join(prefix, suffix) |
205 for prefix in prefix_list for suffix in suffix_list ] | 205 for suffix in suffix_list for prefix in prefix_list ] |
206 | 206 |
207 def GetCandidates(dirs, filepart, candidate_fun): | 207 |
208 def _GetChromeOutputDirCandidates(): | |
johnme
2015/10/20 15:40:20
This could perhaps reuse existing logic:
sys.path
agrieve
2015/10/20 18:24:27
Done.
| |
209 """Returns a list of output directories to look in.""" | |
210 out_dir = os.environ.get('CHROMIUM_OUTPUT_DIR') | |
211 if out_dir: | |
212 return [out_dir] | |
213 out_dir = os.environ.get('CHROMIUM_OUT_DIR', 'out') | |
214 out_dir = os.path.join(CHROME_SRC, out_dir) | |
215 buildtype = os.environ.get('BUILDTYPE') | |
216 if buildtype: | |
217 buildtype_list = [ buildtype ] | |
218 else: | |
219 buildtype_list = [ 'Debug', 'Release' ] | |
220 return PathListJoin([out_dir], buildtype_list) | |
221 | |
222 | |
223 def GetCandidates(dirs, filepart, candidate_fun, sort=True): | |
208 """Returns a list of candidate filenames. | 224 """Returns a list of candidate filenames. |
209 | 225 |
210 Args: | 226 Args: |
211 dirs: a list of the directory part of the pathname. | 227 dirs: a list of the directory part of the pathname. |
212 filepart: the file part of the pathname. | 228 filepart: the file part of the pathname. |
213 candidate_fun: a function to apply to each candidate, returns a list. | 229 candidate_fun: a function to apply to each candidate, returns a list. |
230 sort: Whether to sort by modification time (newest first). | |
214 | 231 |
215 Returns: | 232 Returns: |
216 A list of candidate files ordered by modification time, newest first. | 233 A list of candidate files filtered by candidate_fun, in the order given. |
217 """ | 234 """ |
218 out_dir = os.environ.get('CHROMIUM_OUT_DIR', 'out') | 235 candidates = PathListJoin(dirs, [filepart]) |
219 out_dir = os.path.join(CHROME_SYMBOLS_DIR, out_dir) | |
220 buildtype = os.environ.get('BUILDTYPE') | |
221 if buildtype: | |
222 buildtype_list = [ buildtype ] | |
223 else: | |
224 buildtype_list = [ 'Debug', 'Release' ] | |
225 | |
226 candidates = PathListJoin([out_dir], buildtype_list) + [CHROME_SYMBOLS_DIR] | |
227 candidates = PathListJoin(candidates, dirs) | |
228 candidates = PathListJoin(candidates, [filepart]) | |
229 logging.debug('GetCandidates: prefiltered candidates = %s' % candidates) | 236 logging.debug('GetCandidates: prefiltered candidates = %s' % candidates) |
230 candidates = list( | 237 candidates = list( |
231 itertools.chain.from_iterable(map(candidate_fun, candidates))) | 238 itertools.chain.from_iterable(map(candidate_fun, candidates))) |
232 candidates = sorted(candidates, key=os.path.getmtime, reverse=True) | 239 if sort: |
240 candidates.sort(key=os.path.getmtime, reverse=True) | |
233 return candidates | 241 return candidates |
234 | 242 |
235 def GetCandidateApks(): | 243 def GetCandidateApks(): |
236 """Returns a list of APKs which could contain the library. | 244 """Returns a list of APKs which could contain the library. |
237 | 245 |
238 Args: | 246 Args: |
239 None | 247 None |
240 | 248 |
241 Returns: | 249 Returns: |
242 list of APK filename which could contain the library. | 250 list of APK filename which could contain the library. |
243 """ | 251 """ |
244 return GetCandidates(['apks'], '*.apk', glob.glob) | 252 dirs = PathListJoin(_GetChromeOutputDirCandidates(), ['apks']) |
253 return GetCandidates(dirs, '*.apk', glob.glob, sort=True) | |
245 | 254 |
246 def GetCrazyLib(apk_filename): | 255 def GetCrazyLib(apk_filename): |
247 """Returns the name of the first crazy library from this APK. | 256 """Returns the name of the first crazy library from this APK. |
248 | 257 |
249 Args: | 258 Args: |
250 apk_filename: name of an APK file. | 259 apk_filename: name of an APK file. |
251 | 260 |
252 Returns: | 261 Returns: |
253 Name of the first library which would be crazy loaded from this APK. | 262 Name of the first library which would be crazy loaded from this APK. |
254 """ | 263 """ |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 Returns: | 296 Returns: |
288 Name of the library which corresponds to that APK. | 297 Name of the library which corresponds to that APK. |
289 """ | 298 """ |
290 matching_apks = GetMatchingApks(device_apk_name) | 299 matching_apks = GetMatchingApks(device_apk_name) |
291 logging.debug('MapDeviceApkToLibrary: matching_apks=%s' % matching_apks) | 300 logging.debug('MapDeviceApkToLibrary: matching_apks=%s' % matching_apks) |
292 for matching_apk in matching_apks: | 301 for matching_apk in matching_apks: |
293 crazy_lib = GetCrazyLib(matching_apk) | 302 crazy_lib = GetCrazyLib(matching_apk) |
294 if crazy_lib: | 303 if crazy_lib: |
295 return crazy_lib | 304 return crazy_lib |
296 | 305 |
306 def GetLibrarySearchPaths(): | |
307 if CHROME_SYMBOLS_DIR: | |
308 return [CHROME_SYMBOLS_DIR] | |
309 dirs = _GetChromeOutputDirCandidates() | |
310 return PathListJoin(dirs, ['lib.unstripped', 'lib', 'lib.target', '.']) | |
311 | |
297 def GetCandidateLibraries(library_name): | 312 def GetCandidateLibraries(library_name): |
298 """Returns a list of candidate library filenames. | 313 """Returns a list of candidate library filenames. |
299 | 314 |
300 Args: | 315 Args: |
301 library_name: basename of the library to match. | 316 library_name: basename of the library to match. |
302 | 317 |
303 Returns: | 318 Returns: |
304 A list of matching library filenames for library_name. | 319 A list of matching library filenames for library_name. |
305 """ | 320 """ |
321 # Sorting doens't work for native libraries because the stripped version is | |
johnme
2015/10/20 15:40:20
doesn't
agrieve
2015/10/20 18:24:27
Done.
| |
322 # always newer than the unstripped version. | |
johnme
2015/10/20 15:40:20
Hmm, but not sorting seems a risky way to get the
agrieve
2015/10/20 18:24:27
Like it. ;)
| |
306 return GetCandidates( | 323 return GetCandidates( |
307 ['lib', 'lib.target', '.'], library_name, | 324 GetLibrarySearchPaths(), library_name, |
308 lambda filename: filter(os.path.exists, [filename])) | 325 lambda filename: filter(os.path.exists, [filename]), |
326 sort=False) | |
309 | 327 |
310 def TranslateLibPath(lib): | 328 def TranslateLibPath(lib): |
311 # The filename in the stack trace maybe an APK name rather than a library | 329 # The filename in the stack trace maybe an APK name rather than a library |
312 # name. This happens when the library was loaded directly from inside the | 330 # name. This happens when the library was loaded directly from inside the |
313 # APK. If this is the case we try to figure out the library name by looking | 331 # APK. If this is the case we try to figure out the library name by looking |
314 # for a matching APK file and finding the name of the library in contains. | 332 # for a matching APK file and finding the name of the library in contains. |
315 # The name of the APK file on the device is of the form | 333 # The name of the APK file on the device is of the form |
316 # <package_name>-<number>.apk. The APK file on the host may have any name | 334 # <package_name>-<number>.apk. The APK file on the host may have any name |
317 # so we look at the APK badging to see if the package name matches. | 335 # so we look at the APK badging to see if the package name matches. |
318 apk = GetApkFromLibrary(lib) | 336 apk = GetApkFromLibrary(lib) |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 process.stdin.write("\n") | 609 process.stdin.write("\n") |
592 process.stdin.close() | 610 process.stdin.close() |
593 demangled_symbol = process.stdout.readline().strip() | 611 demangled_symbol = process.stdout.readline().strip() |
594 process.stdout.close() | 612 process.stdout.close() |
595 return demangled_symbol | 613 return demangled_symbol |
596 | 614 |
597 def FormatSymbolWithOffset(symbol, offset): | 615 def FormatSymbolWithOffset(symbol, offset): |
598 if offset == 0: | 616 if offset == 0: |
599 return symbol | 617 return symbol |
600 return "%s+%d" % (symbol, offset) | 618 return "%s+%d" % (symbol, offset) |
OLD | NEW |