config.test_source_root = os.path.dirname(__file__)
config.test_exec_root = config.test_source_root
-if 'Address' in config.llvm_use_sanitizer:
- config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1'
- # macOS flags needed for LLDB built with address sanitizer.
- if 'Darwin' in config.host_os and 'x86' in config.host_triple:
- import subprocess
- resource_dir = subprocess.check_output(
- [config.cmake_cxx_compiler,
- '-print-resource-dir']).decode('utf-8').strip()
- runtime = os.path.join(resource_dir, 'lib', 'darwin',
- 'libclang_rt.asan_osx_dynamic.dylib')
- config.environment['DYLD_INSERT_LIBRARIES'] = runtime
+
+def mkdir_p(path):
+ import errno
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+ if not os.path.isdir(path):
+ raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
+
+
+def find_sanitizer_runtime(name):
+ import subprocess
+ resource_dir = subprocess.check_output(
+ [config.cmake_cxx_compiler,
+ '-print-resource-dir']).decode('utf-8').strip()
+ return os.path.join(resource_dir, 'lib', 'darwin', name)
def find_shlibpath_var():
yield 'PATH'
+# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python
+# binary as the ASan interceptors get loaded too late. Also, when SIP is
+# enabled, we can't inject libraries into system binaries at all, so we need a
+# copy of the "real" python to work with.
+def find_python_interpreter():
+ # Avoid doing any work if we already copied the binary.
+ copied_python = os.path.join(config.lldb_build_directory, 'copied-python')
+ if os.path.isfile(copied_python):
+ return copied_python
+
+ # Find the "real" python binary.
+ import shutil, subprocess
+ real_python = subprocess.check_output([
+ config.python_executable,
+ os.path.join(os.path.dirname(os.path.realpath(__file__)),
+ 'get_darwin_real_python.py')
+ ]).decode('utf-8').strip()
+
+ shutil.copy(real_python, copied_python)
+
+ # Now make sure the copied Python works. The Python in Xcode has a relative
+ # RPATH and cannot be copied.
+ try:
+ # We don't care about the output, just make sure it runs.
+ subprocess.check_output([copied_python, '-V'], stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError:
+ # The copied Python didn't work. Assume we're dealing with the Python
+ # interpreter in Xcode. Given that this is not a system binary SIP
+ # won't prevent us form injecting the interceptors so we get away with
+ # not copying the executable.
+ os.remove(copied_python)
+ return real_python
+
+ # The copied Python works.
+ return copied_python
+
+
+if 'Address' in config.llvm_use_sanitizer:
+ config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1'
+ if 'Darwin' in config.host_os and 'x86' in config.host_triple:
+ config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime(
+ 'libclang_rt.asan_osx_dynamic.dylib')
+
+if 'Thread' in config.llvm_use_sanitizer:
+ if 'Darwin' in config.host_os and 'x86' in config.host_triple:
+ config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime(
+ 'libclang_rt.tsan_osx_dynamic.dylib')
+
+if 'DYLD_INSERT_LIBRARIES' in config.environment and platform.system() == 'Darwin':
+ config.python_executable = find_python_interpreter()
+
# Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent.
if config.shared_libs:
for shlibpath_var in find_shlibpath_var():
if config.filecheck:
dotest_cmd += ['--filecheck', config.filecheck]
+if config.yaml2obj:
+ dotest_cmd += ['--yaml2obj', config.yaml2obj]
+
if config.lldb_libs_dir:
dotest_cmd += ['--lldb-libs-dir', config.lldb_libs_dir]
+if 'lldb-repro-capture' in config.available_features or \
+ 'lldb-repro-replay' in config.available_features:
+ dotest_cmd += ['--skip-category=lldb-vscode', '--skip-category=std-module']
+
if config.enabled_plugins:
for plugin in config.enabled_plugins:
dotest_cmd += ['--enable-plugin', plugin]