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 # pylint: disable=no-member
54 return symbol
.TranslateLibPath(library
)
57 def _Symbolize(asan_input
):
58 asan_libs
= _FindASanLibraries()
59 libraries
= collections
.defaultdict(list)
61 for asan_log_line
in [a
.rstrip() for a
in asan_input
]:
62 m
= _ParseAsanLogLine(asan_log_line
)
64 libraries
[m
['library']].append(m
)
65 asan_lines
.append({'raw_log': asan_log_line
, 'parsed': m
})
67 all_symbols
= collections
.defaultdict(dict)
68 for library
, items
in libraries
.iteritems():
69 libname
= _TranslateLibPath(library
, asan_libs
)
70 lib_relative_addrs
= set([i
['rel_address'] for i
in items
])
71 # pylint: disable=no-member
72 info_dict
= symbol
.SymbolInformationForSet(libname
,
76 all_symbols
[library
]['symbols'] = info_dict
78 for asan_log_line
in asan_lines
:
79 m
= asan_log_line
['parsed']
81 print asan_log_line
['raw_log']
83 if (m
['library'] in all_symbols
and
84 m
['rel_address'] in all_symbols
[m
['library']]['symbols']):
85 s
= all_symbols
[m
['library']]['symbols'][m
['rel_address']][0]
86 print '%s%s %s %s' % (m
['prefix'], m
['pos'], s
[0], s
[1])
88 print asan_log_line
['raw_log']
92 parser
= optparse
.OptionParser()
93 parser
.add_option('-l', '--logcat',
94 help='File containing adb logcat output with ASan stacks. '
95 'Use stdin if not specified.')
96 options
, _
= parser
.parse_args()
98 asan_input
= file(options
.logcat
, 'r')
100 asan_input
= sys
.stdin
101 _Symbolize(asan_input
.readlines())
104 if __name__
== "__main__":