Chromium Code Reviews| Index: tracing/bin/symbolize_trace |
| diff --git a/tracing/bin/symbolize_trace b/tracing/bin/symbolize_trace |
| index ecfbb673bf0c46bbbcb4dce0f414a68388f237fe..105b9e943ee34a7fa5dc08c7d3856941331bad33 100755 |
| --- a/tracing/bin/symbolize_trace |
| +++ b/tracing/bin/symbolize_trace |
| @@ -55,7 +55,8 @@ def FindInSystemPath(binary_name): |
| def IsSymbolizableFile(file_path): |
| result = subprocess.check_output(['file', '-0', file_path]) |
| type_string = result[result.find('\0') + 1:] |
| - return bool(re.match(r'\: (ELF|Mach-O) (32|64)-bit\b', type_string)) |
| + return bool(re.match(r'.*(ELF|Mach-O) (32|64)-bit\b.*', |
| + type_string, re.DOTALL)) |
| class ProcessMemoryMaps(object): |
| @@ -271,7 +272,7 @@ def ResolveSymbolizableFiles(processes): |
| return symfile_by_path.values() |
| -def SymbolizeFiles(symfiles, addr2line_path): |
| +def SymbolizeFiles(symfiles, symbolizer_path): |
| """Symbolizes each file in the given list of SymbolizableFiles |
| and updates stack frames with symbolization results.""" |
| print 'Symbolizing...' |
| @@ -301,37 +302,54 @@ def SymbolizeFiles(symfiles, addr2line_path): |
| frame.name = unsymbolized_name |
| continue |
| - def _SymbolizerCallback(sym_info, frames): |
| - # Unwind inline chain to the top. |
| - while sym_info.inlined_by: |
| - sym_info = sym_info.inlined_by |
| - |
| - symbolized_name = sym_info.name if sym_info.name else unsymbolized_name |
| - for frame in frames: |
| - frame.name = symbolized_name |
| - |
| - symbolizer = elf_symbolizer.ELFSymbolizer(symfile.symbolizable_path, |
| - addr2line_path, |
| - _SymbolizerCallback, |
| - inlines=True) |
| - |
| _SubPrintf('Symbolizing {} PCs from {}...', |
| len(symfile.frames_by_address), |
| symfile.path) |
| - for address, frames in symfile.frames_by_address.iteritems(): |
| - # SymbolizeAsync() asserts that the type of address is int. We operate |
| - # on longs (since they are raw pointers possibly from 64-bit processes). |
| - # It's OK to cast here because we're passing relative PC, which should |
| - # always fit into int. |
| - symbolizer.SymbolizeAsync(int(address), frames) |
| - |
| - symbolizer.Join() |
| + if sys.platform == 'darwin': |
|
DmitrySkiba
2017/01/10 21:28:09
We have this check in two places - first when we d
erikchen
2017/02/04 02:34:56
Introducing a class to avoid an extra conditional
|
| + SymbolizeMac(symfile, symbolizer_path) |
| + else: |
| + SymbolizeLinuxAndAndroid(sym_file, symbolizer_path) |
| symbolized = True |
| return symbolized |
| +def SymbolizeLinuxAndAndroid(sym_file, symbolizer_path): |
| + def _SymbolizerCallback(sym_info, frames): |
| + # Unwind inline chain to the top. |
| + while sym_info.inlined_by: |
| + sym_info = sym_info.inlined_by |
| + |
| + symbolized_name = sym_info.name if sym_info.name else unsymbolized_name |
| + for frame in frames: |
| + frame.name = symbolized_name |
| + |
| + symbolizer = elf_symbolizer.ELFSymbolizer(symfile.symbolizable_path, |
| + symbolizer_path, |
| + _SymbolizerCallback, |
| + inlines=True) |
| + |
| + for address, frames in symfile.frames_by_address.iteritems(): |
| + # SymbolizeAsync() asserts that the type of address is int. We operate |
| + # on longs (since they are raw pointers possibly from 64-bit processes). |
| + # It's OK to cast here because we're passing relative PC, which should |
| + # always fit into int. |
| + symbolizer.SymbolizeAsync(int(address), frames) |
| + |
| + symbolizer.Join() |
| + |
| + |
| +def SymbolizeMac(symfile, symbolizer_path): |
| + cmd = [symbolizer_path, '-arch', 'x86_64', '-l', |
| + '0x0', '-o' , symfile.symbolizable_path] |
| + cmd.extend([hex(int(x)) for x in symfile.frames_by_address.keys()]) |
|
DmitrySkiba
2017/01/10 21:28:09
What is the max command line length on macOS? This
erikchen
2017/02/04 02:34:56
By default, the max length is 260k characters. I'v
|
| + output_array = subprocess.check_output(cmd).split('\n') |
| + for i in range(len(symfile.frames_by_address.keys())): |
| + for frame in symfile.frames_by_address.values()[i]: |
| + frame.name = output_array[i] |
| + |
| + |
| def HaveFilesFromAndroid(symfiles): |
| return any(ANDROID_PATH_MATCHER.match(f.path) for f in symfiles) |
| @@ -372,9 +390,13 @@ def main(): |
| else: |
| return open(trace_file_path, mode + 't') |
| - addr2line_path = FindInSystemPath('addr2line') |
| - if addr2line_path is None: |
| - sys.exit("Can't symbolize - no addr2line in PATH.") |
| + if sys.platform == 'darwin': |
| + symbolizer = 'atos' |
| + else: |
| + symbolizer = 'addr2line' |
| + symbolizer_path = FindInSystemPath(symbolizer) |
| + if symbolizer_path is None: |
| + sys.exit("Can't symbolize - no %s in PATH." % symbolizer) |
| print 'Reading trace file...' |
| with _OpenTraceFile('r') as trace_file: |
| @@ -392,7 +414,7 @@ def main(): |
| 'symbolize it.') |
| RemapAndroidFiles(symfiles, os.path.abspath(options.output_directory)) |
| - if SymbolizeFiles(symfiles, addr2line_path): |
| + if SymbolizeFiles(symfiles, symbolizer_path): |
| if options.backup: |
| backup_file_path = trace_file_path + BACKUP_FILE_TAG |
| print 'Backing up trace file to {}...'.format(backup_file_path) |