Skip to content

Commit af97c4b

Browse files
authored
Merge pull request #1585 from JDevlieghere/🍒/python-changes
🍒/python changes
2 parents 59561be + 711673d commit af97c4b

File tree

2 files changed

+77
-54
lines changed

2 files changed

+77
-54
lines changed

lldb/test/API/lit.cfg.py

+71-14
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,25 @@
2020
config.test_source_root = os.path.dirname(__file__)
2121
config.test_exec_root = config.test_source_root
2222

23-
if 'Address' in config.llvm_use_sanitizer:
24-
config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1'
25-
# Swift's libReflection builds without ASAN, which causes a known
26-
# false positive in std::vector.
27-
config.environment['ASAN_OPTIONS'] += ':detect_container_overflow=0'
28-
# macOS flags needed for LLDB built with address sanitizer.
29-
if 'Darwin' in config.host_os and 'x86' in config.host_triple:
30-
import subprocess
31-
resource_dir = subprocess.check_output(
32-
[config.cmake_cxx_compiler,
33-
'-print-resource-dir']).decode('utf-8').strip()
34-
runtime = os.path.join(resource_dir, 'lib', 'darwin',
35-
'libclang_rt.asan_osx_dynamic.dylib')
36-
config.environment['DYLD_INSERT_LIBRARIES'] = runtime
23+
24+
def mkdir_p(path):
25+
import errno
26+
try:
27+
os.makedirs(path)
28+
except OSError as e:
29+
if e.errno != errno.EEXIST:
30+
raise
31+
if not os.path.isdir(path):
32+
raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
33+
34+
35+
def find_sanitizer_runtime(name):
36+
import subprocess
37+
resource_dir = subprocess.check_output(
38+
[config.cmake_cxx_compiler,
39+
'-print-resource-dir']).decode('utf-8').strip()
40+
return os.path.join(resource_dir, 'lib', 'darwin', name)
41+
3742

3843
def find_shlibpath_var():
3944
if platform.system() in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']:
@@ -43,6 +48,58 @@ def find_shlibpath_var():
4348
elif platform.system() == 'Windows':
4449
yield 'PATH'
4550

51+
52+
# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python
53+
# binary as the ASan interceptors get loaded too late. Also, when SIP is
54+
# enabled, we can't inject libraries into system binaries at all, so we need a
55+
# copy of the "real" python to work with.
56+
def find_python_interpreter():
57+
# Avoid doing any work if we already copied the binary.
58+
copied_python = os.path.join(config.lldb_build_directory, 'copied-python')
59+
if os.path.isfile(copied_python):
60+
return copied_python
61+
62+
# Find the "real" python binary.
63+
import shutil, subprocess
64+
real_python = subprocess.check_output([
65+
config.python_executable,
66+
os.path.join(os.path.dirname(os.path.realpath(__file__)),
67+
'get_darwin_real_python.py')
68+
]).decode('utf-8').strip()
69+
70+
shutil.copy(real_python, copied_python)
71+
72+
# Now make sure the copied Python works. The Python in Xcode has a relative
73+
# RPATH and cannot be copied.
74+
try:
75+
# We don't care about the output, just make sure it runs.
76+
subprocess.check_output([copied_python, '-V'], stderr=subprocess.STDOUT)
77+
except subprocess.CalledProcessError:
78+
# The copied Python didn't work. Assume we're dealing with the Python
79+
# interpreter in Xcode. Given that this is not a system binary SIP
80+
# won't prevent us form injecting the interceptors so we get away with
81+
# not copying the executable.
82+
os.remove(copied_python)
83+
return real_python
84+
85+
# The copied Python works.
86+
return copied_python
87+
88+
89+
if 'Address' in config.llvm_use_sanitizer:
90+
config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1'
91+
if 'Darwin' in config.host_os and 'x86' in config.host_triple:
92+
config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime(
93+
'libclang_rt.asan_osx_dynamic.dylib')
94+
95+
if 'Thread' in config.llvm_use_sanitizer:
96+
if 'Darwin' in config.host_os and 'x86' in config.host_triple:
97+
config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime(
98+
'libclang_rt.tsan_osx_dynamic.dylib')
99+
100+
if 'DYLD_INSERT_LIBRARIES' in config.environment and platform.system() == 'Darwin':
101+
config.python_executable = find_python_interpreter()
102+
46103
# Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent.
47104
if config.shared_libs:
48105
for shlibpath_var in find_shlibpath_var():

lldb/test/API/lldbtest.py

+6-40
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,6 @@
1010
import lit.util
1111
from lit.formats.base import TestFormat
1212

13-
def getBuildDir(cmd):
14-
found = False
15-
for arg in cmd:
16-
if found:
17-
return arg
18-
if arg == '--build-dir':
19-
found = True
20-
return None
21-
22-
def mkdir_p(path):
23-
import errno
24-
try:
25-
os.makedirs(path)
26-
except OSError as e:
27-
if e.errno != errno.EEXIST:
28-
raise
29-
if not os.path.isdir(path):
30-
raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
3113

3214
class LLDBTest(TestFormat):
3315
def __init__(self, dotest_cmd):
@@ -63,31 +45,15 @@ def execute(self, test, litConfig):
6345
return (lit.Test.UNSUPPORTED, 'Test is unsupported')
6446

6547
testPath, testFile = os.path.split(test.getSourcePath())
48+
49+
# The Python used to run lit can be different from the Python LLDB was
50+
# build with.
51+
executable = test.config.python_executable
52+
6653
# On Windows, the system does not always correctly interpret
6754
# shebang lines. To make sure we can execute the tests, add
6855
# python exe as the first parameter of the command.
69-
cmd = [sys.executable] + self.dotest_cmd + [testPath, '-p', testFile]
70-
71-
# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim
72-
# python binary as the ASan interceptors get loaded too late. Also,
73-
# when SIP is enabled, we can't inject libraries into system binaries
74-
# at all, so we need a copy of the "real" python to work with.
75-
#
76-
# Find the "real" python binary, copy it, and invoke it.
77-
if 'DYLD_INSERT_LIBRARIES' in test.config.environment and \
78-
platform.system() == 'Darwin':
79-
builddir = getBuildDir(cmd)
80-
mkdir_p(builddir)
81-
copied_python = os.path.join(builddir, 'copied-system-python')
82-
if not os.path.isfile(copied_python):
83-
import shutil, subprocess
84-
python = subprocess.check_output([
85-
sys.executable,
86-
os.path.join(os.path.dirname(os.path.realpath(__file__)),
87-
'get_darwin_real_python.py')
88-
]).decode('utf-8').strip()
89-
shutil.copy(python, copied_python)
90-
cmd[0] = copied_python
56+
cmd = [executable] + self.dotest_cmd + [testPath, '-p', testFile]
9157

9258
timeoutInfo = None
9359
try:

0 commit comments

Comments
 (0)