17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#!/usr/bin/env python 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# found in the LICENSE file. 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport collections 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport optparse 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport os 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport re 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport sys 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfrom pylib import constants 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Uses symbol.py from third_party/android_platform, not python's. 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochsys.path.insert(0, 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch os.path.join(constants.DIR_SOURCE_ROOT, 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'third_party/android_platform/development/scripts')) 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport symbol 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)_RE_ASAN = re.compile(r'(.*?)(#\S*?) (\S*?) \((.*?)\+(.*?)\)') 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef _ParseAsanLogLine(line): 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch m = re.match(_RE_ASAN, line) 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not m: 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return None 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return { 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'prefix': m.group(1), 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'library': m.group(4), 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'pos': m.group(2), 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'rel_address': '%08x' % int(m.group(5), 16), 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef _FindASanLibraries(): 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch asan_lib_dir = os.path.join(constants.DIR_SOURCE_ROOT, 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'third_party', 'llvm-build', 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'Release+Asserts', 'lib') 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch asan_libs = [] 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for src_dir, _, files in os.walk(asan_lib_dir): 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch asan_libs += [os.path.relpath(os.path.join(src_dir, f)) 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for f in files 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if f.endswith('.so')] 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return asan_libs 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef _TranslateLibPath(library, asan_libs): 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for asan_lib in asan_libs: 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if os.path.basename(library) == os.path.basename(asan_lib): 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return '/' + asan_lib 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return symbol.TranslateLibPath(library) 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochdef _Symbolize(asan_input): 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch asan_libs = _FindASanLibraries() 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch libraries = collections.defaultdict(list) 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch asan_lines = [] 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for asan_log_line in [a.rstrip() for a in asan_input]: 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch m = _ParseAsanLogLine(asan_log_line) 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if m: 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch libraries[m['library']].append(m) 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch asan_lines.append({'raw_log': asan_log_line, 'parsed': m}) 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch all_symbols = collections.defaultdict(dict) 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for library, items in libraries.iteritems(): 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch libname = _TranslateLibPath(library, asan_libs) 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch lib_relative_addrs = set([i['rel_address'] for i in items]) 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch info_dict = symbol.SymbolInformationForSet(libname, 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch lib_relative_addrs, 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch True) 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if info_dict: 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch all_symbols[library]['symbols'] = info_dict 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for asan_log_line in asan_lines: 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch m = asan_log_line['parsed'] 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not m: 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print asan_log_line['raw_log'] 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch continue 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (m['library'] in all_symbols and 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch m['rel_address'] in all_symbols[m['library']]['symbols']): 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s = all_symbols[m['library']]['symbols'][m['rel_address']][0] 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch print '%s%s %s %s' % (m['prefix'], m['pos'], s[0], s[1]) 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print asan_log_line['raw_log'] 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef main(): 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parser = optparse.OptionParser() 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parser.add_option('-l', '--logcat', 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch help='File containing adb logcat output with ASan stacks. ' 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'Use stdin if not specified.') 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch options, _ = parser.parse_args() 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if options.logcat: 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch asan_input = file(options.logcat, 'r') 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch asan_input = sys.stdin 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch _Symbolize(asan_input.readlines()) 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochif __name__ == "__main__": 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.exit(main()) 104