3 # Copyright 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
14 from pylib
import constants
16 # Uses symbol.py from third_party/android_platform, not python's.
18 os
.path
.join(constants
.DIR_SOURCE_ROOT
,
19 'third_party/android_platform/development/scripts'))
23 _RE_ASAN
= re
.compile(r
'(.*?)(#\S*?) (\S*?) \((.*?)\+(.*?)\)')
25 def _ParseAsanLogLine(line
):
26 m
= re
.match(_RE_ASAN
, line
)
31 'library': m
.group(4),
33 'rel_address': '%08x' % int(m
.group(5), 16),
37 def _FindASanLibraries():
38 asan_lib_dir
= os
.path
.join(constants
.DIR_SOURCE_ROOT
,
39 'third_party', 'llvm-build',
40 'Release+Asserts', 'lib')
42 for src_dir
, _
, files
in os
.walk(asan_lib_dir
):
43 asan_libs
+= [os
.path
.relpath(os
.path
.join(src_dir
, f
))
49 def _TranslateLibPath(library
, asan_libs
):
50 for asan_lib
in asan_libs
:
51 if os
.path
.basename(library
) == os
.path
.basename(asan_lib
):
53 return symbol
.TranslateLibPath(library
)
56 def _Symbolize(asan_input
):
57 asan_libs
= _FindASanLibraries()
58 libraries
= collections
.defaultdict(list)
60 for asan_log_line
in [a
.rstrip() for a
in asan_input
]:
61 m
= _ParseAsanLogLine(asan_log_line
)
63 libraries
[m
['library']].append(m
)
64 asan_lines
.append({'raw_log': asan_log_line
, 'parsed': m
})
66 all_symbols
= collections
.defaultdict(dict)
67 for library
, items
in libraries
.iteritems():
68 libname
= _TranslateLibPath(library
, asan_libs
)
69 lib_relative_addrs
= set([i
['rel_address'] for i
in items
])
70 info_dict
= symbol
.SymbolInformationForSet(libname
,
74 all_symbols
[library
]['symbols'] = info_dict
76 for asan_log_line
in asan_lines
:
77 m
= asan_log_line
['parsed']
79 print asan_log_line
['raw_log']
81 if (m
['library'] in all_symbols
and
82 m
['rel_address'] in all_symbols
[m
['library']]['symbols']):
83 s
= all_symbols
[m
['library']]['symbols'][m
['rel_address']][0]
84 print '%s%s %s %s' % (m
['prefix'], m
['pos'], s
[0], s
[1])
86 print asan_log_line
['raw_log']
90 parser
= optparse
.OptionParser()
91 parser
.add_option('-l', '--logcat',
92 help='File containing adb logcat output with ASan stacks. '
93 'Use stdin if not specified.')
94 options
, _
= parser
.parse_args()
96 asan_input
= file(options
.logcat
, 'r')
98 asan_input
= sys
.stdin
99 _Symbolize(asan_input
.readlines())
102 if __name__
== "__main__":