Chromium Code Reviews| 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 |