17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#!/usr/bin/env python 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Copyright (C) 2013 The Android Open Source Project 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Licensed under the Apache License, Version 2.0 (the "License"); 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# you may not use this file except in compliance with the License. 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# You may obtain a copy of the License at 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# http://www.apache.org/licenses/LICENSE-2.0 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Unless required by applicable law or agreed to in writing, software 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# distributed under the License is distributed on an "AS IS" BASIS, 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# See the License for the specific language governing permissions and 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# limitations under the License. 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch"""stack symbolizes native crash dumps.""" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport getopt 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport glob 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport os 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport sys 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport stack_core 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport subprocess 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport symbol 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport sys 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochDEFAULT_SYMROOT='/tmp/symbols' 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef PrintUsage(): 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """Print usage and exit with error.""" 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # pylint: disable-msg=C6310 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " usage: " + sys.argv[0] + " [options] [FILE]" 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " --symbols-dir=path" 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " the path to a symbols dir, such as =/tmp/out/target/product/dream/symbols" 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " --chrome-symbols-dir=path" 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " the path to a Chrome symbols dir (can be absolute or relative" 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " to src), such as =out/Debug/lib" 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " If not specified, will look for the newest lib in out/Debug or" 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " out/Release" 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " --symbols-zip=path" 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " the path to a symbols zip file, such as =dream-symbols-12345.zip" 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " --more-info" 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " --less-info" 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " Change the level of detail in the output." 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " --more-info is slower and more verbose, but more functions will" 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " be fully qualified with namespace/classname and have full" 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " argument information. Also, the 'stack data' section will be" 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " printed." 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) print " --arch=arm|arm64|x86_64|x86|mips" 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " the target architecture" 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " FILE should contain a stack trace in it somewhere" 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " the tool will find that and re-print it with" 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " source files and line numbers. If you don't" 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " pass FILE, or if file is -, it reads from" 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print " stdin." 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # pylint: enable-msg=C6310 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.exit(1) 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef UnzipSymbols(symbolfile, symdir=None): 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """Unzips a file to DEFAULT_SYMROOT and returns the unzipped location. 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Args: 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symbolfile: The .zip file to unzip 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symdir: Optional temporary directory to use for extraction 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Returns: 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch A tuple containing (the directory into which the zip file was unzipped, 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch the path to the "symbols" directory in the unzipped file). To clean 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch up, the caller can delete the first element of the tuple. 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Raises: 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SymbolDownloadException: When the unzip fails. 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """ 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not symdir: 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symdir = "%s/%s" % (DEFAULT_SYMROOT, hash(symbolfile)) 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not os.path.exists(symdir): 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch os.makedirs(symdir) 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print "extracting %s..." % symbolfile 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch saveddir = os.getcwd() 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch os.chdir(symdir) 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch try: 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile]) 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if unzipcode > 0: 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch os.remove(symbolfile) 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch raise SymbolDownloadException("failed to extract symbol files (%s)." 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch % symbolfile) 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch finally: 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch os.chdir(saveddir) 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch android_symbols = glob.glob("%s/out/target/product/*/symbols" % symdir) 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if android_symbols: 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return (symdir, android_symbols[0]) 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # This is a zip of Chrome symbols, so symbol.CHROME_SYMBOLS_DIR needs to be 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # updated to point here. 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symbol.CHROME_SYMBOLS_DIR = symdir 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return (symdir, symdir) 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef main(): 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch try: 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch options, arguments = getopt.getopt(sys.argv[1:], "", 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ["more-info", 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "less-info", 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "chrome-symbols-dir=", 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "symbols-dir=", 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "symbols-zip=", 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "arch=", 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "help"]) 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch except getopt.GetoptError, unused_error: 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PrintUsage() 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch zip_arg = None 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch more_info = False 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for option, value in options: 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if option == "--help": 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PrintUsage() 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif option == "--symbols-dir": 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symbol.SYMBOLS_DIR = os.path.expanduser(value) 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif option == "--symbols-zip": 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch zip_arg = os.path.expanduser(value) 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif option == "--arch": 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symbol.ARCH = value 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif option == "--chrome-symbols-dir": 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch symbol.CHROME_SYMBOLS_DIR = os.path.join(symbol.CHROME_SYMBOLS_DIR, value) 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif option == "--more-info": 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch more_info = True 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif option == "--less-info": 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch more_info = False 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if len(arguments) > 1: 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PrintUsage() 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not arguments or arguments[0] == "-": 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print "Reading native crash info from stdin" 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch f = sys.stdin 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print "Searching for native crashes in %s" % arguments[0] 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch f = open(arguments[0], "r") 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch lines = f.readlines() 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch f.close() 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch rootdir = None 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if zip_arg: 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg) 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print "Reading Android symbols from", symbol.SYMBOLS_DIR 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print "Reading Chrome symbols from", symbol.CHROME_SYMBOLS_DIR 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stack_core.ConvertTrace(lines, more_info) 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if rootdir: 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # be a good citizen and clean up...os.rmdir and os.removedirs() don't work 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cmd = "rm -rf \"%s\"" % rootdir 1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print "\ncleaning up (%s)" % cmd 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch os.system(cmd) 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochif __name__ == "__main__": 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch main() 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# vi: ts=2 sw=2 173