3 # Copyright (C) 2013 The Android Open Source Project
5 # Licensed under the Apache License, Version 2.0 (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
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 """stack symbolizes native crash dumps."""
29 DEFAULT_SYMROOT
='/tmp/symbols'
32 """Print usage and exit with error."""
33 # pylint: disable-msg=C6310
35 print " usage: " + sys
.argv
[0] + " [options] [FILE]"
37 print " --symbols-dir=path"
38 print " the path to a symbols dir, such as =/tmp/out/target/product/dream/symbols"
40 print " --chrome-symbols-dir=path"
41 print " the path to a Chrome symbols dir (can be absolute or relative"
42 print " to src), such as =out/Debug/lib"
43 print " If not specified, will look for the newest lib in out/Debug or"
46 print " --symbols-zip=path"
47 print " the path to a symbols zip file, such as =dream-symbols-12345.zip"
51 print " Change the level of detail in the output."
52 print " --more-info is slower and more verbose, but more functions will"
53 print " be fully qualified with namespace/classname and have full"
54 print " argument information. Also, the 'stack data' section will be"
57 print " --arch=arm|arm64|x64|x86|mips"
58 print " the target architecture"
60 print " FILE should contain a stack trace in it somewhere"
61 print " the tool will find that and re-print it with"
62 print " source files and line numbers. If you don't"
63 print " pass FILE, or if file is -, it reads from"
66 # pylint: enable-msg=C6310
69 def UnzipSymbols(symbolfile
, symdir
=None):
70 """Unzips a file to DEFAULT_SYMROOT and returns the unzipped location.
73 symbolfile: The .zip file to unzip
74 symdir: Optional temporary directory to use for extraction
77 A tuple containing (the directory into which the zip file was unzipped,
78 the path to the "symbols" directory in the unzipped file). To clean
79 up, the caller can delete the first element of the tuple.
82 SymbolDownloadException: When the unzip fails.
85 symdir
= "%s/%s" % (DEFAULT_SYMROOT
, hash(symbolfile
))
86 if not os
.path
.exists(symdir
):
89 print "extracting %s..." % symbolfile
90 saveddir
= os
.getcwd()
93 unzipcode
= subprocess
.call(["unzip", "-qq", "-o", symbolfile
])
96 raise SymbolDownloadException("failed to extract symbol files (%s)."
101 android_symbols
= glob
.glob("%s/out/target/product/*/symbols" % symdir
)
103 return (symdir
, android_symbols
[0])
105 # This is a zip of Chrome symbols, so symbol.CHROME_SYMBOLS_DIR needs to be
106 # updated to point here.
107 symbol
.CHROME_SYMBOLS_DIR
= symdir
108 return (symdir
, symdir
)
113 options
, arguments
= getopt
.getopt(sys
.argv
[1:], "",
116 "chrome-symbols-dir=",
121 except getopt
.GetoptError
, unused_error
:
126 for option
, value
in options
:
127 if option
== "--help":
129 elif option
== "--symbols-dir":
130 symbol
.SYMBOLS_DIR
= os
.path
.expanduser(value
)
131 elif option
== "--symbols-zip":
132 zip_arg
= os
.path
.expanduser(value
)
133 elif option
== "--arch":
135 elif option
== "--chrome-symbols-dir":
136 symbol
.CHROME_SYMBOLS_DIR
= os
.path
.join(symbol
.CHROME_SYMBOLS_DIR
, value
)
137 elif option
== "--more-info":
139 elif option
== "--less-info":
142 if len(arguments
) > 1:
145 if not arguments
or arguments
[0] == "-":
146 print "Reading native crash info from stdin"
149 print "Searching for native crashes in %s" % arguments
[0]
150 f
= open(arguments
[0], "r")
152 lines
= f
.readlines()
157 rootdir
, symbol
.SYMBOLS_DIR
= UnzipSymbols(zip_arg
)
159 print "Reading Android symbols from", symbol
.SYMBOLS_DIR
160 print "Reading Chrome symbols from", symbol
.CHROME_SYMBOLS_DIR
161 stack_core
.ConvertTrace(lines
, more_info
)
164 # be a good citizen and clean up...os.rmdir and os.removedirs() don't work
165 cmd
= "rm -rf \"%s\"" % rootdir
166 print "\ncleaning up (%s)" % cmd
169 if __name__
== "__main__":