15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from third_party import asan_symbolize
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import os
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LineBuffered(object):
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  """Disable buffering on a file object."""
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  def __init__(self, stream):
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    self.stream = stream
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  def write(self, data):
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    self.stream.write(data)
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if '\n' in data:
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      self.stream.flush()
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  def __getattr__(self, attr):
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return getattr(self.stream, attr)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)def disable_buffering():
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  """Makes this process and child processes stdout unbuffered."""
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if not os.environ.get('PYTHONUNBUFFERED'):
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    # Since sys.stdout is a C++ object, it's impossible to do
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    # sys.stdout.write = lambda...
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sys.stdout = LineBuffered(sys.stdout)
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    os.environ['PYTHONUNBUFFERED'] = 'x'
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidef set_symbolizer_path():
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  """Set the path to the llvm-symbolize binary in the Chromium source tree."""
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if not os.environ.get('LLVM_SYMBOLIZER_PATH'):
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    script_dir = os.path.dirname(os.path.abspath(__file__))
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    # Assume this script resides three levels below src/ (i.e.
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    # src/tools/valgrind/asan/).
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    src_root = os.path.join(script_dir, "..", "..", "..")
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    symbolizer_path = os.path.join(src_root, 'third_party',
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        'llvm-build', 'Release+Asserts', 'bin', 'llvm-symbolizer')
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    assert(os.path.isfile(symbolizer_path))
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    os.environ['LLVM_SYMBOLIZER_PATH'] = os.path.abspath(symbolizer_path)
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def main():
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  disable_buffering()
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  set_symbolizer_path()
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  asan_symbolize.demangle = True
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  asan_symbolize.fix_filename_patterns = sys.argv[1:]
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  asan_symbolize.logfile = sys.stdin
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  loop = asan_symbolize.SymbolizationLoop()
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  loop.process_logfile()
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  main()
59