- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / android_platform / development / scripts / stack
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2013 The Android Open Source Project
4 #
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
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 """stack symbolizes native crash dumps."""
18
19 import getopt
20 import glob
21 import os
22 import sys
23
24 import stack_core
25 import subprocess
26 import symbol
27 import sys
28
29 DEFAULT_SYMROOT='/tmp/symbols'
30
31 def PrintUsage():
32   """Print usage and exit with error."""
33   # pylint: disable-msg=C6310
34   print
35   print "  usage: " + sys.argv[0] + " [options] [FILE]"
36   print
37   print "  --symbols-dir=path"
38   print "       the path to a symbols dir, such as =/tmp/out/target/product/dream/symbols"
39   print
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"
44   print "       out/Release"
45   print
46   print "  --symbols-zip=path"
47   print "       the path to a symbols zip file, such as =dream-symbols-12345.zip"
48   print
49   print "  --more-info"
50   print "  --less-info"
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"
55   print "       printed."
56   print
57   print "  --arch=arm|x86"
58   print "       the target architecture"
59   print
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"
64   print "       stdin."
65   print
66   # pylint: enable-msg=C6310
67   sys.exit(1)
68
69 def UnzipSymbols(symbolfile, symdir=None):
70   """Unzips a file to DEFAULT_SYMROOT and returns the unzipped location.
71
72   Args:
73     symbolfile: The .zip file to unzip
74     symdir: Optional temporary directory to use for extraction
75
76   Returns:
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.
80
81   Raises:
82     SymbolDownloadException: When the unzip fails.
83   """
84   if not symdir:
85     symdir = "%s/%s" % (DEFAULT_SYMROOT, hash(symbolfile))
86   if not os.path.exists(symdir):
87     os.makedirs(symdir)
88
89   print "extracting %s..." % symbolfile
90   saveddir = os.getcwd()
91   os.chdir(symdir)
92   try:
93     unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile])
94     if unzipcode > 0:
95       os.remove(symbolfile)
96       raise SymbolDownloadException("failed to extract symbol files (%s)."
97                                     % symbolfile)
98   finally:
99     os.chdir(saveddir)
100
101   android_symbols = glob.glob("%s/out/target/product/*/symbols" % symdir)
102   if android_symbols:
103     return (symdir, android_symbols[0])
104   else:
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)
109
110
111 def main():
112   try:
113     options, arguments = getopt.getopt(sys.argv[1:], "",
114                                        ["more-info",
115                                         "less-info",
116                                         "chrome-symbols-dir=",
117                                         "symbols-dir=",
118                                         "symbols-zip=",
119                                         "arch=",
120                                         "help"])
121   except getopt.GetoptError, unused_error:
122     PrintUsage()
123
124   zip_arg = None
125   more_info = False
126   for option, value in options:
127     if option == "--help":
128       PrintUsage()
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":
134       symbol.ARCH = value
135     elif option == "--chrome-symbols-dir":
136       symbol.CHROME_SYMBOLS_DIR = os.path.join(symbol.CHROME_SYMBOLS_DIR, value)
137     elif option == "--more-info":
138       more_info = True
139     elif option == "--less-info":
140       more_info = False
141
142   if len(arguments) > 1:
143     PrintUsage()
144
145   if not arguments or arguments[0] == "-":
146     print "Reading native crash info from stdin"
147     f = sys.stdin
148   else:
149     print "Searching for native crashes in %s" % arguments[0]
150     f = open(arguments[0], "r")
151
152   lines = f.readlines()
153   f.close()
154
155   rootdir = None
156   if zip_arg:
157     rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg)
158
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)
162
163   if rootdir:
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
167     os.system(cmd)
168
169 if __name__ == "__main__":
170   main()
171
172 # vi: ts=2 sw=2