Skip to content

🍒/python changes #1585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 71 additions & 14 deletions lldb/test/API/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,25 @@
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'
# Swift's libReflection builds without ASAN, which causes a known
# false positive in std::vector.
config.environment['ASAN_OPTIONS'] += ':detect_container_overflow=0'
# 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():
if platform.system() in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']:
Expand All @@ -43,6 +48,58 @@ def find_shlibpath_var():
elif platform.system() == 'Windows':
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():
Expand Down
46 changes: 6 additions & 40 deletions lldb/test/API/lldbtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,6 @@
import lit.util
from lit.formats.base import TestFormat

def getBuildDir(cmd):
found = False
for arg in cmd:
if found:
return arg
if arg == '--build-dir':
found = True
return None

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)

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

testPath, testFile = os.path.split(test.getSourcePath())

# The Python used to run lit can be different from the Python LLDB was
# build with.
executable = test.config.python_executable

# On Windows, the system does not always correctly interpret
# shebang lines. To make sure we can execute the tests, add
# python exe as the first parameter of the command.
cmd = [sys.executable] + self.dotest_cmd + [testPath, '-p', testFile]

# 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.
#
# Find the "real" python binary, copy it, and invoke it.
if 'DYLD_INSERT_LIBRARIES' in test.config.environment and \
platform.system() == 'Darwin':
builddir = getBuildDir(cmd)
mkdir_p(builddir)
copied_python = os.path.join(builddir, 'copied-system-python')
if not os.path.isfile(copied_python):
import shutil, subprocess
python = subprocess.check_output([
sys.executable,
os.path.join(os.path.dirname(os.path.realpath(__file__)),
'get_darwin_real_python.py')
]).decode('utf-8').strip()
shutil.copy(python, copied_python)
cmd[0] = copied_python
cmd = [executable] + self.dotest_cmd + [testPath, '-p', testFile]

timeoutInfo = None
try:
Expand Down