| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Sets environment variables needed to run a chromium unit test.""" | 6 """Sets environment variables needed to run a chromium unit test.""" |
| 7 | 7 |
| 8 import os | 8 import os |
| 9 import stat | 9 import stat |
| 10 import subprocess | 10 import subprocess |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 def fix_python_path(cmd): | 45 def fix_python_path(cmd): |
| 46 """Returns the fixed command line to call the right python executable.""" | 46 """Returns the fixed command line to call the right python executable.""" |
| 47 out = cmd[:] | 47 out = cmd[:] |
| 48 if out[0] == 'python': | 48 if out[0] == 'python': |
| 49 out[0] = sys.executable | 49 out[0] = sys.executable |
| 50 elif out[0].endswith('.py'): | 50 elif out[0].endswith('.py'): |
| 51 out.insert(0, sys.executable) | 51 out.insert(0, sys.executable) |
| 52 return out | 52 return out |
| 53 | 53 |
| 54 | 54 |
| 55 def get_sanitizer_env(cmd, asan, lsan, msan, tsan): | 55 def get_sanitizer_env(cmd, asan, lsan, msan, tsan, cfi_diag): |
| 56 """Returns the envirnoment flags needed for sanitizer tools.""" | 56 """Returns the envirnoment flags needed for sanitizer tools.""" |
| 57 | 57 |
| 58 extra_env = {} | 58 extra_env = {} |
| 59 | 59 |
| 60 # Instruct GTK to use malloc while running sanitizer-instrumented tests. | 60 # Instruct GTK to use malloc while running sanitizer-instrumented tests. |
| 61 extra_env['G_SLICE'] = 'always-malloc' | 61 extra_env['G_SLICE'] = 'always-malloc' |
| 62 | 62 |
| 63 extra_env['NSS_DISABLE_ARENA_FREE_LIST'] = '1' | 63 extra_env['NSS_DISABLE_ARENA_FREE_LIST'] = '1' |
| 64 extra_env['NSS_DISABLE_UNLOAD'] = '1' | 64 extra_env['NSS_DISABLE_UNLOAD'] = '1' |
| 65 | 65 |
| 66 # TODO(glider): remove the symbolizer path once | 66 # TODO(glider): remove the symbolizer path once |
| 67 # https://code.google.com/p/address-sanitizer/issues/detail?id=134 is fixed. | 67 # https://code.google.com/p/address-sanitizer/issues/detail?id=134 is fixed. |
| 68 symbolizer_path = os.path.join(ROOT_DIR, | 68 symbolizer_path = os.path.join(ROOT_DIR, |
| 69 'third_party', 'llvm-build', 'Release+Asserts', 'bin', 'llvm-symbolizer') | 69 'third_party', 'llvm-build', 'Release+Asserts', 'bin', 'llvm-symbolizer') |
| 70 | 70 |
| 71 if lsan or tsan: | 71 if lsan or tsan: |
| 72 # LSan is not sandbox-compatible, so we can use online symbolization. In | 72 # LSan is not sandbox-compatible, so we can use online symbolization. In |
| 73 # fact, it needs symbolization to be able to apply suppressions. | 73 # fact, it needs symbolization to be able to apply suppressions. |
| 74 symbolization_options = ['symbolize=1', | 74 symbolization_options = ['symbolize=1', |
| 75 'external_symbolizer_path=%s' % symbolizer_path] | 75 'external_symbolizer_path=%s' % symbolizer_path] |
| 76 elif (asan or msan) and sys.platform not in ['win32', 'cygwin']: | 76 elif (asan or msan or cfi_diag) and sys.platform not in ['win32', 'cygwin']: |
| 77 # ASan uses a script for offline symbolization, except on Windows. | 77 # ASan uses a script for offline symbolization, except on Windows. |
| 78 # Important note: when running ASan with leak detection enabled, we must use | 78 # Important note: when running ASan with leak detection enabled, we must use |
| 79 # the LSan symbolization options above. | 79 # the LSan symbolization options above. |
| 80 symbolization_options = ['symbolize=0'] | 80 symbolization_options = ['symbolize=0'] |
| 81 # Set the path to llvm-symbolizer to be used by asan_symbolize.py | 81 # Set the path to llvm-symbolizer to be used by asan_symbolize.py |
| 82 extra_env['LLVM_SYMBOLIZER_PATH'] = symbolizer_path | 82 extra_env['LLVM_SYMBOLIZER_PATH'] = symbolizer_path |
| 83 else: | 83 else: |
| 84 symbolization_options = [] | 84 symbolization_options = [] |
| 85 | 85 |
| 86 if asan: | 86 if asan: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 113 if msan: | 113 if msan: |
| 114 msan_options = symbolization_options[:] | 114 msan_options = symbolization_options[:] |
| 115 if lsan: | 115 if lsan: |
| 116 msan_options.append('detect_leaks=1') | 116 msan_options.append('detect_leaks=1') |
| 117 extra_env['MSAN_OPTIONS'] = ' '.join(msan_options) | 117 extra_env['MSAN_OPTIONS'] = ' '.join(msan_options) |
| 118 | 118 |
| 119 if tsan: | 119 if tsan: |
| 120 tsan_options = symbolization_options[:] | 120 tsan_options = symbolization_options[:] |
| 121 extra_env['TSAN_OPTIONS'] = ' '.join(tsan_options) | 121 extra_env['TSAN_OPTIONS'] = ' '.join(tsan_options) |
| 122 | 122 |
| 123 # CFI uses the UBSan runtime to provide diagnostics. |
| 124 if cfi_diag: |
| 125 ubsan_options = symbolization_options[:] + ['print_stacktrace=1'] |
| 126 extra_env['UBSAN_OPTIONS'] = ' '.join(ubsan_options) |
| 127 |
| 123 return extra_env | 128 return extra_env |
| 124 | 129 |
| 125 | 130 |
| 126 def get_sanitizer_symbolize_command(json_path=None, executable_path=None): | 131 def get_sanitizer_symbolize_command(json_path=None, executable_path=None): |
| 127 """Construct the command to invoke offline symbolization script.""" | 132 """Construct the command to invoke offline symbolization script.""" |
| 128 script_path = os.path.join( | 133 script_path = os.path.join( |
| 129 ROOT_DIR, 'tools', 'valgrind', 'asan', 'asan_symbolize.py') | 134 ROOT_DIR, 'tools', 'valgrind', 'asan', 'asan_symbolize.py') |
| 130 cmd = [sys.executable, script_path] | 135 cmd = [sys.executable, script_path] |
| 131 if json_path is not None: | 136 if json_path is not None: |
| 132 cmd.append('--test-summary-json-file=%s' % json_path) | 137 cmd.append('--test-summary-json-file=%s' % json_path) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 # Used by base/base_paths_linux.cc as an override. Just make sure the default | 183 # Used by base/base_paths_linux.cc as an override. Just make sure the default |
| 179 # logic is used. | 184 # logic is used. |
| 180 env.pop('CR_SOURCE_ROOT', None) | 185 env.pop('CR_SOURCE_ROOT', None) |
| 181 extra_env.update(get_sandbox_env(env)) | 186 extra_env.update(get_sandbox_env(env)) |
| 182 | 187 |
| 183 # Copy logic from tools/build/scripts/slave/runtest.py. | 188 # Copy logic from tools/build/scripts/slave/runtest.py. |
| 184 asan = '--asan=1' in cmd | 189 asan = '--asan=1' in cmd |
| 185 lsan = '--lsan=1' in cmd | 190 lsan = '--lsan=1' in cmd |
| 186 msan = '--msan=1' in cmd | 191 msan = '--msan=1' in cmd |
| 187 tsan = '--tsan=1' in cmd | 192 tsan = '--tsan=1' in cmd |
| 193 cfi_diag = '--cfi-diag=1' in cmd |
| 188 if sys.platform in ['win32', 'cygwin']: | 194 if sys.platform in ['win32', 'cygwin']: |
| 189 # Symbolization works in-process on Windows even when sandboxed. | 195 # Symbolization works in-process on Windows even when sandboxed. |
| 190 use_symbolization_script = False | 196 use_symbolization_script = False |
| 191 else: | 197 else: |
| 192 # LSan doesn't support sandboxing yet, so we use the in-process symbolizer. | 198 # LSan doesn't support sandboxing yet, so we use the in-process symbolizer. |
| 193 # Note that ASan and MSan can work together with LSan. | 199 # Note that ASan and MSan can work together with LSan. |
| 194 use_symbolization_script = (asan or msan) and not lsan | 200 use_symbolization_script = (asan or msan or cfi_diag) and not lsan |
| 195 | 201 |
| 196 if asan or lsan or msan or tsan: | 202 if asan or lsan or msan or tsan or cfi_diag: |
| 197 extra_env.update(get_sanitizer_env(cmd, asan, lsan, msan, tsan)) | 203 extra_env.update(get_sanitizer_env(cmd, asan, lsan, msan, tsan, cfi_diag)) |
| 198 | 204 |
| 199 if lsan or tsan: | 205 if lsan or tsan: |
| 200 # LSan and TSan are not sandbox-friendly. | 206 # LSan and TSan are not sandbox-friendly. |
| 201 cmd.append('--no-sandbox') | 207 cmd.append('--no-sandbox') |
| 202 | 208 |
| 203 cmd = trim_cmd(cmd) | 209 cmd = trim_cmd(cmd) |
| 204 | 210 |
| 205 # Ensure paths are correctly separated on windows. | 211 # Ensure paths are correctly separated on windows. |
| 206 cmd[0] = cmd[0].replace('/', os.path.sep) | 212 cmd[0] = cmd[0].replace('/', os.path.sep) |
| 207 cmd = fix_python_path(cmd) | 213 cmd = fix_python_path(cmd) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 234 print >> sys.stderr, 'Failed to start %s' % cmd | 240 print >> sys.stderr, 'Failed to start %s' % cmd |
| 235 raise | 241 raise |
| 236 | 242 |
| 237 | 243 |
| 238 def main(): | 244 def main(): |
| 239 return run_executable(sys.argv[1:], os.environ.copy()) | 245 return run_executable(sys.argv[1:], os.environ.copy()) |
| 240 | 246 |
| 241 | 247 |
| 242 if __name__ == '__main__': | 248 if __name__ == '__main__': |
| 243 sys.exit(main()) | 249 sys.exit(main()) |
| OLD | NEW |