Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: tracing/tracing/extras/symbolizer/symbolize_trace.py

Issue 2950723002: Add an end-to-end test for symbolize_trace on macOS. (Closed)
Patch Set: lint Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2016 The Chromium Authors. All rights reserved. 2 # Copyright 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 # pylint: disable=too-many-lines 5 # pylint: disable=too-many-lines
6 6
7 """ 7 """
8 This script processes trace files and symbolizes stack frames generated by 8 This script processes trace files and symbolizes stack frames generated by
9 Chrome's native heap profiler. This script assumes that the Chrome binary 9 Chrome's native heap profiler. This script assumes that the Chrome binary
10 referenced in the trace contains symbols, and is the same binary used to emit 10 referenced in the trace contains symbols, and is the same binary used to emit
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 os.path.join(os.path.dirname(__file__), '..', '..', '..')) 230 os.path.join(os.path.dirname(__file__), '..', '..', '..'))
231 231
232 _SYMBOLS_PATH = os.path.abspath(os.path.join( 232 _SYMBOLS_PATH = os.path.abspath(os.path.join(
233 _TRACING_DIR, 233 _TRACING_DIR,
234 'third_party', 234 'third_party',
235 'symbols')) 235 'symbols'))
236 sys.path.append(_SYMBOLS_PATH) 236 sys.path.append(_SYMBOLS_PATH)
237 # pylint: disable=import-error 237 # pylint: disable=import-error
238 import symbols.elf_symbolizer as elf_symbolizer 238 import symbols.elf_symbolizer as elf_symbolizer
239 239
240 from . import symbolize_trace_atos_regex 240 from tracing.extras.symbolizer import symbolize_trace_atos_regex
241 from . import symbolize_trace_macho_reader 241 from tracing.extras.symbolizer import symbolize_trace_macho_reader
242 242
243 _PY_UTILS_PATH = os.path.abspath(os.path.join( 243 _PY_UTILS_PATH = os.path.abspath(os.path.join(
244 _TRACING_DIR, 244 _TRACING_DIR,
245 '..', 245 '..',
246 'common', 246 'common',
247 'py_utils')) 247 'py_utils'))
248 sys.path.append(_PY_UTILS_PATH) 248 sys.path.append(_PY_UTILS_PATH)
249 # pylint: disable=import-error 249 # pylint: disable=import-error
250 import py_utils.cloud_storage as cloud_storage 250 import py_utils.cloud_storage as cloud_storage
251 251
252 _UNNAMED_FILE = 'unnamed'
253
254
252 class NodeWrapper(object): 255 class NodeWrapper(object):
253 """Wraps an event data node(s). 256 """Wraps an event data node(s).
254 257
255 A node is a reference into a trace event JSON. Wrappers parse nodes to 258 A node is a reference into a trace event JSON. Wrappers parse nodes to
256 provide convenient APIs and update nodes when asked to propagate changes 259 provide convenient APIs and update nodes when asked to propagate changes
257 back (see ApplyModifications() below). 260 back (see ApplyModifications() below).
258 261
259 Here is an example of legacy metadata event that contains stack frame tree: 262 Here is an example of legacy metadata event that contains stack frame tree:
260 263
261 { 264 {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 }, 313 },
311 ... 314 ...
312 ] 315 ]
313 } 316 }
314 """ 317 """
315 318
316 class Region(object): 319 class Region(object):
317 def __init__(self, start_address, size, file_path): 320 def __init__(self, start_address, size, file_path):
318 self._start_address = start_address 321 self._start_address = start_address
319 self._size = size 322 self._size = size
320 self._file_path = file_path 323 self._file_path = file_path if file_path else _UNNAMED_FILE
321 324
322 @property 325 @property
323 def start_address(self): 326 def start_address(self):
324 return self._start_address 327 return self._start_address
325 328
326 @property 329 @property
327 def end_address(self): 330 def end_address(self):
328 return self._start_address + self._size 331 return self._start_address + self._size
329 332
330 @property 333 @property
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 """Holds file path, addresses to symbolize and stack frames to update. 982 """Holds file path, addresses to symbolize and stack frames to update.
980 983
981 This class is a link between ELFSymbolizer and a trace file: it specifies 984 This class is a link between ELFSymbolizer and a trace file: it specifies
982 what to symbolize (addresses) and what to update with the symbolization 985 what to symbolize (addresses) and what to update with the symbolization
983 result (frames). 986 result (frames).
984 """ 987 """
985 def __init__(self, file_path): 988 def __init__(self, file_path):
986 self.path = file_path 989 self.path = file_path
987 self.symbolizable_path = file_path # path to use for symbolization 990 self.symbolizable_path = file_path # path to use for symbolization
988 self.frames_by_address = collections.defaultdict(list) 991 self.frames_by_address = collections.defaultdict(list)
992 self.skip_symbolization = False
989 993
990 994
991 def ResolveSymbolizableFiles(processes): 995 def ResolveSymbolizableFiles(processes):
992 """Resolves and groups PCs into list of SymbolizableFiles. 996 """Resolves and groups PCs into list of SymbolizableFiles.
993 997
994 As part of the grouping process, this function resolves PC from each stack 998 As part of the grouping process, this function resolves PC from each stack
995 frame to the corresponding mmap region. Stack frames that failed to resolve 999 frame to the corresponding mmap region. Stack frames that failed to resolve
996 are symbolized with '<unresolved>'. 1000 are symbolized with '<unresolved>'.
997 """ 1001 """
998 symfile_by_path = {} 1002 symfile_by_path = {}
999 for process in processes: 1003 for process in processes:
1000 if not process.memory_map: 1004 if not process.memory_map:
1001 continue 1005 continue
1002 for frame in process.stack_frame_map.frame_by_id.itervalues(): 1006 for frame in process.stack_frame_map.frame_by_id.itervalues():
1003 if frame.pc is None: 1007 if frame.pc is None:
1004 continue 1008 continue
1005 region = process.memory_map.FindRegion(frame.pc) 1009 region = process.memory_map.FindRegion(frame.pc)
1006 if region is None: 1010 if region is None:
1007 frame.name = '<unresolved>' 1011 frame.name = '<unresolved>'
1008 continue 1012 continue
1009 1013
1010 symfile = symfile_by_path.get(region.file_path) 1014 symfile = symfile_by_path.get(region.file_path)
1011 if symfile is None: 1015 if symfile is None:
1012 symfile = SymbolizableFile(region.file_path) 1016 file_path = region.file_path
1017 symfile = SymbolizableFile(file_path)
1013 symfile_by_path[symfile.path] = symfile 1018 symfile_by_path[symfile.path] = symfile
1014 1019
1015 relative_pc = frame.pc - region.start_address 1020 relative_pc = frame.pc - region.start_address
1016 symfile.frames_by_address[relative_pc].append(frame) 1021 symfile.frames_by_address[relative_pc].append(frame)
1017 return symfile_by_path.values() 1022 return symfile_by_path.values()
1018 1023
1019 1024
1020 def FindInSystemPath(binary_name): 1025 def FindInSystemPath(binary_name):
1021 paths = os.environ['PATH'].split(os.pathsep) 1026 paths = os.environ['PATH'].split(os.pathsep)
1022 for path in paths: 1027 for path in paths:
(...skipping 11 matching lines...) Expand all
1034 self.is_win = sys.platform == 'win32' 1039 self.is_win = sys.platform == 'win32'
1035 if self.is_mac: 1040 if self.is_mac:
1036 self.binary = 'atos' 1041 self.binary = 'atos'
1037 self._matcher = symbolize_trace_atos_regex.AtosRegexMatcher() 1042 self._matcher = symbolize_trace_atos_regex.AtosRegexMatcher()
1038 elif self.is_win: 1043 elif self.is_win:
1039 self.binary = 'addr2line-pdb.exe' 1044 self.binary = 'addr2line-pdb.exe'
1040 else: 1045 else:
1041 self.binary = 'addr2line' 1046 self.binary = 'addr2line'
1042 self.symbolizer_path = FindInSystemPath(self.binary) 1047 self.symbolizer_path = FindInSystemPath(self.binary)
1043 1048
1044 def _SymbolizeLinuxAndAndroid(self, symfile, unsymbolized_name): 1049 def _SymbolizeLinuxAndAndroid(self, symfile):
1045 def _SymbolizerCallback(sym_info, frames): 1050 def _SymbolizerCallback(sym_info, frames):
1046 # Unwind inline chain to the top. 1051 # Unwind inline chain to the top.
1047 while sym_info.inlined_by: 1052 while sym_info.inlined_by:
1048 sym_info = sym_info.inlined_by 1053 sym_info = sym_info.inlined_by
1049 1054
1050 symbolized_name = sym_info.name if sym_info.name else unsymbolized_name 1055 symbolized_name = (sym_info.name if sym_info.name else
1056 '<{}>'.format(symfile.path))
1051 for frame in frames: 1057 for frame in frames:
1052 frame.name = symbolized_name 1058 frame.name = symbolized_name
1053 1059
1054 symbolizer = elf_symbolizer.ELFSymbolizer(symfile.symbolizable_path, 1060 symbolizer = elf_symbolizer.ELFSymbolizer(symfile.symbolizable_path,
1055 self.symbolizer_path, 1061 self.symbolizer_path,
1056 _SymbolizerCallback, 1062 _SymbolizerCallback,
1057 inlines=True) 1063 inlines=True)
1058 1064
1059 for address, frames in symfile.frames_by_address.iteritems(): 1065 for address, frames in symfile.frames_by_address.iteritems():
1060 # SymbolizeAsync() asserts that the type of address is int. We operate 1066 # SymbolizeAsync() asserts that the type of address is int. We operate
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 stdout_data = stdout_data.split('\n') 1120 stdout_data = stdout_data.split('\n')
1115 1121
1116 # This is known to be in the same order as stderr_data. 1122 # This is known to be in the same order as stderr_data.
1117 for i, addr in enumerate(addrs): 1123 for i, addr in enumerate(addrs):
1118 for frame in symfile.frames_by_address[int(addr, 16)]: 1124 for frame in symfile.frames_by_address[int(addr, 16)]:
1119 # Output of addr2line with --functions is always 2 outputs per 1125 # Output of addr2line with --functions is always 2 outputs per
1120 # symbol, function name followed by source line number. Only grab 1126 # symbol, function name followed by source line number. Only grab
1121 # the function name as line info is not always available. 1127 # the function name as line info is not always available.
1122 frame.name = stdout_data[i * 2] 1128 frame.name = stdout_data[i * 2]
1123 1129
1124 def Symbolize(self, symfile, unsymbolized_name): 1130 def SymbolizeSymfile(self, symfile):
1131 if symfile.skip_symbolization:
1132 for address, frames in symfile.frames_by_address.iteritems():
1133 unsymbolized_name = ('<' + os.path.basename(symfile.symbolizable_path)
1134 + '>')
1135 # Only append the address if there's a library.
1136 if symfile.symbolizable_path != _UNNAMED_FILE:
1137 unsymbolized_name += ' + ' + str(hex(address))
1138
1139 for frame in frames:
1140 frame.name = unsymbolized_name
1141 return
1142
1125 if self.is_mac: 1143 if self.is_mac:
1126 self._SymbolizeMac(symfile) 1144 self._SymbolizeMac(symfile)
1127 elif self.is_win: 1145 elif self.is_win:
1128 self._SymbolizeWin(symfile) 1146 self._SymbolizeWin(symfile)
1129 else: 1147 else:
1130 self._SymbolizeLinuxAndAndroid(symfile, unsymbolized_name) 1148 self._SymbolizeLinuxAndAndroid(symfile)
1131 1149
1132 def IsSymbolizableFile(self, file_path): 1150 def IsSymbolizableFile(self, file_path):
1133 if self.is_win: 1151 if self.is_win:
1134 extension = os.path.splitext(file_path)[1].lower() 1152 extension = os.path.splitext(file_path)[1].lower()
1135 return extension in ['.dll', '.exe'] 1153 return extension in ['.dll', '.exe']
1136 else: 1154 else:
1137 result = subprocess.check_output(['file', '-0', file_path]) 1155 result = subprocess.check_output(['file', '-0', file_path])
1138 type_string = result[result.find('\0') + 1:] 1156 type_string = result[result.find('\0') + 1:]
1139 return bool(re.match(r'.*(ELF|Mach-O) (32|64)-bit\b.*', 1157 return bool(re.match(r'.*(ELF|Mach-O) (32|64)-bit\b.*',
1140 type_string, re.DOTALL)) 1158 type_string, re.DOTALL))
1141 1159
1142 1160
1143 def SymbolizeFiles(symfiles, symbolizer): 1161 def SymbolizeFiles(symfiles, symbolizer):
1144 """Symbolizes each file in the given list of SymbolizableFiles 1162 """Symbolizes each file in the given list of SymbolizableFiles
1145 and updates stack frames with symbolization results.""" 1163 and updates stack frames with symbolization results."""
1146 1164
1147 if not symfiles: 1165 if not symfiles:
1148 print 'Nothing to symbolize.' 1166 print 'Nothing to symbolize.'
1149 return 1167 return
1150 1168
1151 print 'Symbolizing...' 1169 print 'Symbolizing...'
1152 1170
1153 def _SubPrintf(message, *args): 1171 def _SubPrintf(message, *args):
1154 print (' ' + message).format(*args) 1172 print (' ' + message).format(*args)
1155 1173
1156 for symfile in symfiles: 1174 for symfile in symfiles:
1157 unsymbolized_name = '<{}>'.format(
1158 symfile.path if symfile.path else 'unnamed')
1159
1160 problem = None 1175 problem = None
1161 if not os.path.isabs(symfile.symbolizable_path): 1176 if not os.path.isabs(symfile.symbolizable_path):
1162 problem = 'not a file' 1177 problem = 'not a file'
1163 elif not os.path.isfile(symfile.symbolizable_path): 1178 elif not os.path.isfile(symfile.symbolizable_path):
1164 problem = "file doesn't exist" 1179 problem = "file doesn't exist"
1165 elif not symbolizer.IsSymbolizableFile(symfile.symbolizable_path): 1180 elif not symbolizer.IsSymbolizableFile(symfile.symbolizable_path):
1166 problem = 'file is not symbolizable' 1181 problem = 'file is not symbolizable'
1167 if problem: 1182 if problem:
1168 _SubPrintf("Won't symbolize {} PCs for '{}': {}.", 1183 _SubPrintf("Problem with '{}': {}.",
1169 len(symfile.frames_by_address),
1170 symfile.symbolizable_path, 1184 symfile.symbolizable_path,
1171 problem) 1185 problem)
1172 for frames in symfile.frames_by_address.itervalues(): 1186 symfile.skip_symbolization = True
1173 for frame in frames:
1174 frame.name = unsymbolized_name
1175 continue
1176 1187
1177 _SubPrintf('Symbolizing {} PCs from {}...', 1188 _SubPrintf('Symbolizing {} PCs from {}...',
1178 len(symfile.frames_by_address), 1189 len(symfile.frames_by_address),
1179 symfile.symbolizable_path) 1190 symfile.symbolizable_path)
1180 1191
1181 symbolizer.Symbolize(symfile, unsymbolized_name) 1192 symbolizer.SymbolizeSymfile(symfile)
1182 1193
1183 1194
1184 # Matches Android library paths, supports both K (/data/app-lib/<>/lib.so) 1195 # Matches Android library paths, supports both K (/data/app-lib/<>/lib.so)
1185 # as well as L+ (/data/app/<>/lib/<>/lib.so). Library name is available 1196 # as well as L+ (/data/app/<>/lib/<>/lib.so). Library name is available
1186 # via 'name' group. 1197 # via 'name' group.
1187 ANDROID_PATH_MATCHER = re.compile( 1198 ANDROID_PATH_MATCHER = re.compile(
1188 r'^/data/(?:' 1199 r'^/data/(?:'
1189 r'app/[^/]+/lib/[^/]+/|' 1200 r'app/[^/]+/lib/[^/]+/|'
1190 r'app-lib/[^/]+/|' 1201 r'app-lib/[^/]+/|'
1191 r'data/[^/]+/incremental-install-files/lib/' 1202 r'data/[^/]+/incremental-install-files/lib/'
(...skipping 14 matching lines...) Expand all
1206 name = match.group('name') 1217 name = match.group('name')
1207 symfile.symbolizable_path = os.path.join( 1218 symfile.symbolizable_path = os.path.join(
1208 output_path, ANDROID_UNSTRIPPED_SUBPATH, name) 1219 output_path, ANDROID_UNSTRIPPED_SUBPATH, name)
1209 else: 1220 else:
1210 # Clobber file path to trigger "not a file" problem in SymbolizeFiles(). 1221 # Clobber file path to trigger "not a file" problem in SymbolizeFiles().
1211 # Without this, files won't be symbolized with "file not found" problem, 1222 # Without this, files won't be symbolized with "file not found" problem,
1212 # which is not accurate. 1223 # which is not accurate.
1213 symfile.symbolizable_path = 'android://{}'.format(symfile.path) 1224 symfile.symbolizable_path = 'android://{}'.format(symfile.path)
1214 1225
1215 1226
1216 def RemapMacFiles(symfiles, symbol_base_directory, version): 1227 def RemapMacFiles(symfiles, symbol_base_directory, version,
1228 only_symbolize_chrome_symbols):
1217 suffix = ("Google Chrome Framework.dSYM/Contents/Resources/DWARF/" 1229 suffix = ("Google Chrome Framework.dSYM/Contents/Resources/DWARF/"
1218 "Google Chrome Framework") 1230 "Google Chrome Framework")
1219 symbol_sub_dir = os.path.join(symbol_base_directory, version) 1231 symbol_sub_dir = os.path.join(symbol_base_directory, version)
1220 symbolizable_path = os.path.join(symbol_sub_dir, suffix) 1232 symbolizable_path = os.path.join(symbol_sub_dir, suffix)
1221 1233
1222 for symfile in symfiles: 1234 for symfile in symfiles:
1223 if symfile.path.endswith("Google Chrome Framework"): 1235 if symfile.path.endswith("Google Chrome Framework"):
1224 symfile.symbolizable_path = symbolizable_path 1236 symfile.symbolizable_path = symbolizable_path
1237 elif only_symbolize_chrome_symbols:
1238 symfile.skip_symbolization = True
1225 1239
1226 def RemapWinFiles(symfiles, symbol_base_directory, version, is64bit): 1240 def RemapWinFiles(symfiles, symbol_base_directory, version, is64bit,
1241 only_symbolize_chrome_symbols):
1227 folder = "win64" if is64bit else "win" 1242 folder = "win64" if is64bit else "win"
1228 symbol_sub_dir = os.path.join(symbol_base_directory, 1243 symbol_sub_dir = os.path.join(symbol_base_directory,
1229 "chrome-" + folder + "-" + version) 1244 "chrome-" + folder + "-" + version)
1230 for symfile in symfiles: 1245 for symfile in symfiles:
1231 image = os.path.join(symbol_sub_dir, os.path.basename(symfile.path)) 1246 image = os.path.join(symbol_sub_dir, os.path.basename(symfile.path))
1232 symbols = image + ".pdb" 1247 symbols = image + ".pdb"
1233 if os.path.isfile(image) and os.path.isfile(symbols): 1248 if os.path.isfile(image) and os.path.isfile(symbols):
1234 symfile.symbolizable_path = image 1249 symfile.symbolizable_path = image
1250 elif only_symbolize_chrome_symbols:
1251 symfile.skip_symbolization = True
1235 1252
1236 def Symbolize(options, trace, symbolizer): 1253 def SymbolizeTrace(options, trace, symbolizer):
1237 symfiles = ResolveSymbolizableFiles(trace.processes) 1254 symfiles = ResolveSymbolizableFiles(trace.processes)
1238 1255
1239 # Android trace files don't have any indication they are from Android. 1256 # Android trace files don't have any indication they are from Android.
1240 # So we're checking for Android-specific paths. 1257 # So we're checking for Android-specific paths.
1241 if HaveFilesFromAndroid(symfiles): 1258 if HaveFilesFromAndroid(symfiles):
1242 if not options.output_directory: 1259 if not options.output_directory:
1243 sys.exit('The trace file appears to be from Android. Please ' 1260 sys.exit('The trace file appears to be from Android. Please '
1244 'specify output directory to properly symbolize it.') 1261 'specify output directory to properly symbolize it.')
1245 RemapAndroidFiles(symfiles, os.path.abspath(options.output_directory)) 1262 RemapAndroidFiles(symfiles, os.path.abspath(options.output_directory))
1246 1263
1247 1264
1248 if not trace.is_chromium: 1265 if not trace.is_chromium:
1266 # A non-chromium trace probably is not coming from the current machine.
1267 # Don't attempt to symbolize system symbols, as that will produce the wrong
1268 # results.
1269 options.only_symbolize_chrome_symbols = True
1249 if symbolizer.is_mac: 1270 if symbolizer.is_mac:
1250 RemapMacFiles(symfiles, options.symbol_base_directory, trace.version) 1271 RemapMacFiles(symfiles, options.symbol_base_directory, trace.version,
1272 options.only_symbolize_chrome_symbols)
1251 if symbolizer.is_win: 1273 if symbolizer.is_win:
1252 RemapWinFiles(symfiles, options.symbol_base_directory, trace.version, 1274 RemapWinFiles(symfiles, options.symbol_base_directory, trace.version,
1253 trace.is_64bit) 1275 trace.is_64bit, options.only_symbolize_chrome_symbols)
1254 1276
1255 SymbolizeFiles(symfiles, symbolizer) 1277 SymbolizeFiles(symfiles, symbolizer)
1256 1278
1257 1279
1258 def OpenTraceFile(file_path, mode): 1280 def OpenTraceFile(file_path, mode):
1259 if file_path.endswith('.gz'): 1281 if file_path.endswith('.gz'):
1260 return gzip.open(file_path, mode + 'b') 1282 return gzip.open(file_path, mode + 'b')
1261 else: 1283 else:
1262 return open(file_path, mode + 't') 1284 return open(file_path, mode + 't')
1263 1285
1264 1286
1265 def FetchAndExtractSymbolsMac(symbol_base_directory, version): 1287 def FetchAndExtractSymbolsMac(symbol_base_directory, version,
1288 cloud_storage_bucket):
1266 def GetLocalPath(base_dir, version): 1289 def GetLocalPath(base_dir, version):
1267 return os.path.join(base_dir, version + ".tar.bz2") 1290 return os.path.join(base_dir, version + ".tar.bz2")
1268 def GetSymbolsPath(version): 1291 def GetSymbolsPath(version):
1269 return "desktop-*/" + version + "/mac64/Google Chrome.dSYM.tar.bz2" 1292 return "desktop-*/" + version + "/mac64/Google Chrome.dSYM.tar.bz2"
1270 def ExtractSymbolTarFile(symbol_sub_dir, symbol_tar_file): 1293 def ExtractSymbolTarFile(symbol_sub_dir, symbol_tar_file):
1271 os.makedirs(symbol_sub_dir) 1294 os.makedirs(symbol_sub_dir)
1272 with tarfile.open(os.path.expanduser(symbol_tar_file), "r:bz2") as tar: 1295 with tarfile.open(os.path.expanduser(symbol_tar_file), "r:bz2") as tar:
1273 tar.extractall(symbol_sub_dir) 1296 tar.extractall(symbol_sub_dir)
1274 1297
1275 symbol_sub_dir = os.path.join(symbol_base_directory, version) 1298 symbol_sub_dir = os.path.join(symbol_base_directory, version)
1276 if os.path.isdir(symbol_sub_dir): 1299 if os.path.isdir(symbol_sub_dir):
1277 return True 1300 return True
1278 1301
1279 bzip_path = GetLocalPath(symbol_base_directory, version) 1302 bzip_path = GetLocalPath(symbol_base_directory, version)
1280 if not os.path.isfile(bzip_path): 1303 if not os.path.isfile(bzip_path):
1281 1304
1282 cloud_storage_bucket = "chrome-unsigned"
1283 if not cloud_storage.Exists(cloud_storage_bucket, GetSymbolsPath(version)): 1305 if not cloud_storage.Exists(cloud_storage_bucket, GetSymbolsPath(version)):
1284 print "Can't find symbols on GCS." 1306 print "Can't find symbols on GCS."
1285 return False 1307 return False
1286 print "Downloading symbols files from GCS, please wait." 1308 print "Downloading symbols files from GCS, please wait."
1287 cloud_storage.Get(cloud_storage_bucket, GetSymbolsPath(version), bzip_path) 1309 cloud_storage.Get(cloud_storage_bucket, GetSymbolsPath(version), bzip_path)
1288 1310
1289 ExtractSymbolTarFile(symbol_sub_dir, bzip_path) 1311 ExtractSymbolTarFile(symbol_sub_dir, bzip_path)
1290 return True 1312 return True
1291 1313
1292 1314
1293 def FetchAndExtractSymbolsWin(symbol_base_directory, version, is64bit): 1315 def FetchAndExtractSymbolsWin(symbol_base_directory, version, is64bit,
1316 cloud_storage_bucket):
1294 def DownloadAndExtractZipFile(zip_path, source, destination): 1317 def DownloadAndExtractZipFile(zip_path, source, destination):
1295 if not os.path.isfile(zip_path): 1318 if not os.path.isfile(zip_path):
1296 cloud_storage_bucket = "chrome-unsigned"
1297 if not cloud_storage.Exists(cloud_storage_bucket, source): 1319 if not cloud_storage.Exists(cloud_storage_bucket, source):
1298 print "Can't find symbols on GCS." 1320 print "Can't find symbols on GCS."
1299 return False 1321 return False
1300 print "Downloading symbols files from GCS, please wait." 1322 print "Downloading symbols files from GCS, please wait."
1301 cloud_storage.Get(cloud_storage_bucket, source, zip_path) 1323 cloud_storage.Get(cloud_storage_bucket, source, zip_path)
1302 if not os.path.isfile(zip_path): 1324 if not os.path.isfile(zip_path):
1303 print "Can't download symbols on GCS." 1325 print "Can't download symbols on GCS."
1304 return False 1326 return False
1305 with zipfile.ZipFile(zip_path, "r") as zip_file: 1327 with zipfile.ZipFile(zip_path, "r") as zip_file:
1306 for member in zip_file.namelist(): 1328 for member in zip_file.namelist():
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 help='Trace file to symbolize (.json or .json.gz)') 1368 help='Trace file to symbolize (.json or .json.gz)')
1347 1369
1348 parser.add_argument( 1370 parser.add_argument(
1349 '--no-backup', dest='backup', default='true', action='store_false', 1371 '--no-backup', dest='backup', default='true', action='store_false',
1350 help="Don't create {} files".format(BACKUP_FILE_TAG)) 1372 help="Don't create {} files".format(BACKUP_FILE_TAG))
1351 1373
1352 parser.add_argument( 1374 parser.add_argument(
1353 '--output-directory', 1375 '--output-directory',
1354 help='The path to the build output directory, such as out/Debug.') 1376 help='The path to the build output directory, such as out/Debug.')
1355 1377
1378 parser.add_argument(
1379 '--only-symbolize-chrome-symbols',
1380 action='store_true',
1381 help='Prevents symbolization of non-Chrome [system] symbols.')
1382
1383 parser.add_argument(
1384 '--cloud-storage-bucket', default='chrome-unsigned',
1385 help="Bucket that holds symbols for official Chrome builds. "
1386 "Used by tests, which don't have access to the default bucket.")
1387
1356 home_dir = os.path.expanduser('~') 1388 home_dir = os.path.expanduser('~')
1357 default_dir = os.path.join(home_dir, "symbols") 1389 default_dir = os.path.join(home_dir, "symbols")
1358 parser.add_argument( 1390 parser.add_argument(
1359 '--symbol-base-directory', 1391 '--symbol-base-directory',
1360 default=default_dir, 1392 default=default_dir,
1361 help='Directory where symbols are downloaded and cached.') 1393 help='Directory where symbols are downloaded and cached.')
1362 1394
1363 symbolizer = Symbolizer() 1395 symbolizer = Symbolizer()
1364 if symbolizer.symbolizer_path is None: 1396 if symbolizer.symbolizer_path is None:
1365 sys.exit("Can't symbolize - no %s in PATH." % symbolizer.binary) 1397 sys.exit("Can't symbolize - no %s in PATH." % symbolizer.binary)
(...skipping 12 matching lines...) Expand all
1378 return False 1410 return False
1379 1411
1380 # If the trace is from Chromium, assume that symbols are already present. 1412 # If the trace is from Chromium, assume that symbols are already present.
1381 # Otherwise the trace is from Google Chrome. Assume that this is not a local 1413 # Otherwise the trace is from Google Chrome. Assume that this is not a local
1382 # build of Google Chrome with symbols, and that we need to fetch symbols 1414 # build of Google Chrome with symbols, and that we need to fetch symbols
1383 # from gcs. 1415 # from gcs.
1384 if not trace.is_chromium: 1416 if not trace.is_chromium:
1385 has_symbols = False 1417 has_symbols = False
1386 if symbolizer.is_mac: 1418 if symbolizer.is_mac:
1387 has_symbols = FetchAndExtractSymbolsMac(options.symbol_base_directory, 1419 has_symbols = FetchAndExtractSymbolsMac(options.symbol_base_directory,
1388 trace.version) 1420 trace.version,
1421 options.cloud_storage_bucket)
1389 if symbolizer.is_win: 1422 if symbolizer.is_win:
1390 has_symbols = FetchAndExtractSymbolsWin(options.symbol_base_directory, 1423 has_symbols = FetchAndExtractSymbolsWin(options.symbol_base_directory,
1391 trace.version, trace.is_64bit) 1424 trace.version, trace.is_64bit,
1425 options.cloud_storage_bucket)
1392 if not has_symbols: 1426 if not has_symbols:
1393 print 'Cannot fetch symbols from GCS' 1427 print 'Cannot fetch symbols from GCS'
1394 return False 1428 return False
1395 1429
1396 Symbolize(options, trace, symbolizer) 1430 SymbolizeTrace(options, trace, symbolizer)
1397 1431
1398 if trace.modified: 1432 if trace.modified:
1399 trace.ApplyModifications() 1433 trace.ApplyModifications()
1400 1434
1401 if options.backup: 1435 if options.backup:
1402 backup_file_path = trace_file_path + BACKUP_FILE_TAG 1436 backup_file_path = trace_file_path + BACKUP_FILE_TAG
1403 print 'Backing up trace file to {}'.format(backup_file_path) 1437 print 'Backing up trace file to {}'.format(backup_file_path)
1404 os.rename(trace_file_path, backup_file_path) 1438 os.rename(trace_file_path, backup_file_path)
1405 1439
1406 print 'Updating the trace file...' 1440 print 'Updating the trace file...'
1407 with OpenTraceFile(trace_file_path, 'w') as trace_file: 1441 with OpenTraceFile(trace_file_path, 'w') as trace_file:
1408 json.dump(trace.node, trace_file) 1442 json.dump(trace.node, trace_file)
1409 else: 1443 else:
1410 print 'No modifications were made - not updating the trace file.' 1444 print 'No modifications were made - not updating the trace file.'
1445 return True
1411 1446
1412 1447
1413 if __name__ == '__main__': 1448 if __name__ == '__main__':
1414 main(sys.argv[1:]) 1449 main(sys.argv[1:])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698