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 |