OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Utility functions for the stack tool.""" |
| 6 |
| 7 import glob |
| 8 import os |
| 9 import os.path |
| 10 import re |
| 11 |
| 12 |
| 13 def UnzipSymbols(symbolfile, symdir=None): |
| 14 """Unzips a file to _DEFAULT_SYMROOT and returns the unzipped location. |
| 15 |
| 16 Args: |
| 17 symbolfile: The .zip file to unzip |
| 18 symdir: Optional temporary directory to use for extraction |
| 19 |
| 20 Returns: |
| 21 A tuple containing (the directory into which the zip file was unzipped, |
| 22 the path to the "symbols" directory in the unzipped file). To clean |
| 23 up, the caller can delete the first element of the tuple. |
| 24 |
| 25 Raises: |
| 26 SymbolDownloadException: When the unzip fails. |
| 27 """ |
| 28 if not symdir: |
| 29 symdir = "%s/%s" % (_DEFAULT_SYMROOT, hash(symbolfile)) |
| 30 if not os.path.exists(symdir): |
| 31 os.makedirs(symdir) |
| 32 |
| 33 print "extracting %s..." % symbolfile |
| 34 saveddir = os.getcwd() |
| 35 os.chdir(symdir) |
| 36 try: |
| 37 unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile]) |
| 38 if unzipcode > 0: |
| 39 os.remove(symbolfile) |
| 40 raise SymbolDownloadException("failed to extract symbol files (%s)." |
| 41 % symbolfile) |
| 42 finally: |
| 43 os.chdir(saveddir) |
| 44 |
| 45 android_symbols = glob.glob("%s/out/target/product/*/symbols" % symdir) |
| 46 if android_symbols: |
| 47 return (symdir, android_symbols[0]) |
| 48 else: |
| 49 # This is a zip of Chrome symbols, so symbol.CHROME_SYMBOLS_DIR needs to be |
| 50 # updated to point here. |
| 51 symbol.CHROME_SYMBOLS_DIR = symdir |
| 52 return (symdir, symdir) |
| 53 |
| 54 |
| 55 def GetBasenameFromMojoApp(url): |
| 56 """Used by GetSymbolMapping() to extract the basename from the location the |
| 57 mojo app was downloaded from. The location is a URL, e.g. |
| 58 http://foo/bar/x.so.""" |
| 59 index = url.rfind('/') |
| 60 return url[(index + 1):] if index != -1 else url |
| 61 |
| 62 |
| 63 def GetSymboledNameForMojoApp(path): |
| 64 """Used by GetSymbolMapping to get the non-stripped library name for an |
| 65 installed mojo app.""" |
| 66 # e.g. tracing.mojo -> libtracing_library.so |
| 67 name, ext = os.path.splitext(path) |
| 68 if ext != '.mojo': |
| 69 return path |
| 70 return 'lib%s_library.so' % name |
| 71 |
| 72 |
| 73 def GetSymbolMapping(lines): |
| 74 """Returns a mapping (dictionary) from download file to .so.""" |
| 75 regex = re.compile('Caching mojo app (\S+?)(?:\?\S+)? at (\S+)') |
| 76 mappings = {} |
| 77 for line in lines: |
| 78 result = regex.search(line) |
| 79 if result: |
| 80 url = GetBasenameFromMojoApp(result.group(1)) |
| 81 mappings[os.path.normpath(result.group(2))] = GetSymboledNameForMojoApp( |
| 82 url) |
| 83 return mappings |
| 84 |
| 85 |
| 86 def _LowestAncestorContainingRelpath(dir_path, relpath): |
| 87 """Returns the lowest ancestor dir of |dir_path| that contains |relpath|. |
| 88 """ |
| 89 cur_dir_path = os.path.abspath(dir_path) |
| 90 while True: |
| 91 if os.path.exists(os.path.join(cur_dir_path, relpath)): |
| 92 return cur_dir_path |
| 93 |
| 94 next_dir_path = os.path.dirname(cur_dir_path) |
| 95 if next_dir_path != cur_dir_path: |
| 96 cur_dir_path = next_dir_path |
| 97 else: |
| 98 return None |
| 99 |
| 100 |
| 101 def GuessDir(relpath): |
| 102 """Returns absolute path to location |relpath| in the lowest ancestor of this |
| 103 file that contains it.""" |
| 104 lowest_ancestor = _LowestAncestorContainingRelpath( |
| 105 os.path.dirname(__file__), relpath) |
| 106 if not lowest_ancestor: |
| 107 return None |
| 108 return os.path.join(lowest_ancestor, relpath) |
OLD | NEW |