summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-02-14 09:22:10 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-02-14 09:22:10 +0000
commit08c9d0bc3ac37d7d5def0318a1420e67cca53e41 (patch)
treed7a1020610e73102dc5e6342245e01fbb780c9db /lib
parent53aa4fda49f94920139300227786ac47c393f1ce (diff)
[asan] Android test runner for ASan lit tests.
This change replaces 32- and 64- bit config.in-s with a single config template that is used to generate both 32 and 64 bits configs as well as the new arm-android config. Arm-android config is special because it can run tests on a remote device over adb (android debug bridge). We replace %clang with a script that run the compiler, upload the result to the device, and replaces it with another script. The second script runs the binary on the device and delivers stdout/stderr/exitcode back. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@201394 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/asan/lit_tests/64bitConfig/lit.site.cfg.in12
-rw-r--r--lib/asan/lit_tests/CMakeLists.txt59
-rw-r--r--lib/asan/lit_tests/GenericConfig/lit.site.cfg.in (renamed from lib/asan/lit_tests/32bitConfig/lit.site.cfg.in)14
-rw-r--r--lib/asan/lit_tests/android_commands/android_common.py29
-rwxr-xr-xlib/asan/lit_tests/android_commands/android_compile.py36
-rwxr-xr-xlib/asan/lit_tests/android_commands/android_run.py34
-rw-r--r--lib/asan/lit_tests/lit.cfg25
-rw-r--r--lib/lit.common.configured.in29
8 files changed, 183 insertions, 55 deletions
diff --git a/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in b/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in
deleted file mode 100644
index a35994484..000000000
--- a/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in
+++ /dev/null
@@ -1,12 +0,0 @@
-## Autogenerated by LLVM/Clang configuration.
-# Do not edit!
-
-# Load common config for all compiler-rt lit tests.
-lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured")
-
-# Tool-specific config options.
-config.asan_source_dir = "@ASAN_SOURCE_DIR@"
-config.bits = "64"
-
-# Load tool-specific config that would do the real work.
-lit_config.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg")
diff --git a/lib/asan/lit_tests/CMakeLists.txt b/lib/asan/lit_tests/CMakeLists.txt
index 72a3f5439..223052a16 100644
--- a/lib/asan/lit_tests/CMakeLists.txt
+++ b/lib/asan/lit_tests/CMakeLists.txt
@@ -1,36 +1,59 @@
set(ASAN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(ASAN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..)
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/64bitConfig/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig/lit.site.cfg
- )
-
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/32bitConfig/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg
- )
-
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
- )
-
if(COMPILER_RT_CAN_EXECUTE_TESTS)
set(ASAN_TESTSUITES)
- if(CAN_TARGET_i386)
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig)
+
+ if(CAN_TARGET_arm_android)
+ # This is only true if we are cross-compiling.
+ # Build all tests with host compiler and use host tools.
+ set(ASAN_TEST_TARGET_CC ${CMAKE_C_COMPILER})
+ get_filename_component(ASAN_TEST_LLVM_TOOLS_DIR ${CMAKE_C_COMPILER} PATH)
+ set(ASAN_TEST_CONFIG_SUFFIX "-arm-android")
+ set(ASAN_TEST_BITS "32")
+ get_target_flags_for_arch(arm_android ASAN_TEST_TARGET_CFLAGS)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/GenericConfig/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/ARMAndroidConfig/lit.site.cfg
+ )
+ list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/ARMAndroidConfig)
endif()
+
if(CAN_TARGET_x86_64 OR CAN_TARGET_powerpc64)
+ set(ASAN_TEST_CONFIG_SUFFIX "64")
+ set(ASAN_TEST_BITS "64")
+ set(ASAN_TEST_TARGET_CFLAGS ${TARGET_64_BIT_CFLAGS})
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/GenericConfig/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig/lit.site.cfg
+ )
list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig)
endif()
+
+ if(CAN_TARGET_i386)
+ set(ASAN_TEST_CONFIG_SUFFIX "32")
+ set(ASAN_TEST_BITS "32")
+ set(ASAN_TEST_TARGET_CFLAGS ${TARGET_32_BIT_CFLAGS})
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/GenericConfig/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg
+ )
+ list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig)
+ endif()
+
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+ )
+
# Run ASan tests only if we're sure we may produce working binaries.
set(ASAN_TEST_DEPS
${SANITIZER_COMMON_LIT_TEST_DEPS}
asan_runtime_libraries)
set(ASAN_TEST_PARAMS
asan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
- if(LLVM_INCLUDE_TESTS)
+ # FIXME: support unit test in the android test runner
+ if(LLVM_INCLUDE_TESTS AND NOT CAN_TARGET_arm_android)
list(APPEND ASAN_TEST_DEPS AsanUnitTests)
list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
endif()
diff --git a/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in b/lib/asan/lit_tests/GenericConfig/lit.site.cfg.in
index faef4e8c9..7ecf0e581 100644
--- a/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in
+++ b/lib/asan/lit_tests/GenericConfig/lit.site.cfg.in
@@ -1,13 +1,17 @@
## Autogenerated by LLVM/Clang configuration.
# Do not edit!
-# Load common config for all compiler-rt lit tests.
-lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured")
-
# Tool-specific config options.
+config.name_suffix = "@ASAN_TEST_CONFIG_SUFFIX@"
config.asan_source_dir = "@ASAN_SOURCE_DIR@"
-config.bits = "32"
+config.target_cflags = "@ASAN_TEST_TARGET_CFLAGS@"
+config.clang = "@ASAN_TEST_TARGET_CC@"
+config.llvm_tools_dir = "@ASAN_TEST_LLVM_TOOLS_DIR@"
+config.bits = "@ASAN_TEST_BITS@"
+config.android = "@CAN_TARGET_arm_android@"
+
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured")
# Load tool-specific config that would do the real work.
lit_config.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg")
-
diff --git a/lib/asan/lit_tests/android_commands/android_common.py b/lib/asan/lit_tests/android_commands/android_common.py
new file mode 100644
index 000000000..43ac7b48d
--- /dev/null
+++ b/lib/asan/lit_tests/android_commands/android_common.py
@@ -0,0 +1,29 @@
+import os, subprocess, tempfile
+import time
+
+ANDROID_TMPDIR = '/data/local/tmp/Output'
+ADB = os.environ.get('ADB', 'adb')
+
+verbose = False
+if os.environ.get('ANDROID_RUN_VERBOSE') == '1':
+ verbose = True
+
+def adb(args):
+ if verbose:
+ print args
+ devnull = open(os.devnull, 'w')
+ return subprocess.call([ADB] + args, stdout=devnull, stderr=subprocess.STDOUT)
+
+def pull_from_device(path):
+ tmp = tempfile.mktemp()
+ adb(['pull', path, tmp])
+ text = open(tmp, 'r').read()
+ os.unlink(tmp)
+ return text
+
+def push_to_device(path):
+ # Workaround for https://code.google.com/p/android/issues/detail?id=65857
+ dst_path = os.path.join(ANDROID_TMPDIR, os.path.basename(path))
+ tmp_path = dst_path + '.push'
+ adb(['push', path, tmp_path])
+ adb(['shell', 'cp "%s" "%s" 2>&1' % (tmp_path, dst_path)])
diff --git a/lib/asan/lit_tests/android_commands/android_compile.py b/lib/asan/lit_tests/android_commands/android_compile.py
new file mode 100755
index 000000000..4b880886b
--- /dev/null
+++ b/lib/asan/lit_tests/android_commands/android_compile.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+import os, sys, subprocess
+from android_common import *
+
+
+here = os.path.abspath(os.path.dirname(sys.argv[0]))
+android_run = os.path.join(here, 'android_run.py')
+
+output = None
+output_type = 'executable'
+
+args = sys.argv[1:]
+while args:
+ arg = args.pop(0)
+ if arg == '-shared':
+ output_type = 'shared'
+ elif arg == '-c':
+ output_type = 'object'
+ elif arg == '-o':
+ output = args.pop(0)
+
+if output == None:
+ print "No output file name!"
+ sys.exit(1)
+
+ret = subprocess.call(sys.argv[1:])
+if ret != 0:
+ sys.exit(ret)
+
+if output_type in ['executable', 'shared']:
+ push_to_device(output)
+
+if output_type == 'executable':
+ os.rename(output, output + '.real')
+ os.symlink(android_run, output)
diff --git a/lib/asan/lit_tests/android_commands/android_run.py b/lib/asan/lit_tests/android_commands/android_run.py
new file mode 100755
index 000000000..a6ceeb427
--- /dev/null
+++ b/lib/asan/lit_tests/android_commands/android_run.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+import os, sys, subprocess, tempfile
+from android_common import *
+
+ANDROID_TMPDIR = '/data/local/tmp/Output'
+
+here = os.path.abspath(os.path.dirname(sys.argv[0]))
+device_binary = os.path.join(ANDROID_TMPDIR, os.path.basename(sys.argv[0]))
+
+def build_env():
+ args = []
+ # Android linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir.
+ args.append('LD_LIBRARY_PATH=%s:%s' %
+ (ANDROID_TMPDIR, os.environ.get('LD_LIBRARY_PATH', '')))
+ for (key, value) in os.environ.items():
+ if key in ['ASAN_OPTIONS']:
+ args.append('%s="%s"' % (key, value))
+ return ' '.join(args)
+
+device_env = build_env()
+device_args = ' '.join(sys.argv[1:]) # FIXME: escape?
+device_stdout = device_binary + '.stdout'
+device_stderr = device_binary + '.stderr'
+device_exitcode = device_binary + '.exitcode'
+ret = adb(['shell', 'cd %s && %s %s %s >%s 2>%s ; echo $? >%s' %
+ (ANDROID_TMPDIR, device_env, device_binary, device_args,
+ device_stdout, device_stderr, device_exitcode)])
+if ret != 0:
+ sys.exit(ret)
+
+sys.stdout.write(pull_from_device(device_stdout))
+sys.stderr.write(pull_from_device(device_stderr))
+sys.exit(int(pull_from_device(device_exitcode)))
diff --git a/lib/asan/lit_tests/lit.cfg b/lib/asan/lit_tests/lit.cfg
index 71a700c6a..de18cd669 100644
--- a/lib/asan/lit_tests/lit.cfg
+++ b/lib/asan/lit_tests/lit.cfg
@@ -14,7 +14,7 @@ def get_required_attr(config, attr_name):
return attr_value
# Setup config name.
-config.name = 'AddressSanitizer' + config.bits
+config.name = 'AddressSanitizer' + config.name_suffix
# Setup source root.
config.test_source_root = os.path.dirname(__file__)
@@ -53,23 +53,32 @@ if llvm_src_root is None:
# Setup default compiler flags used with -fsanitize=address option.
# FIXME: Review the set of required flags and check if it can be reduced.
-bits_cflag = " -m" + config.bits
+target_cflags = " " + config.target_cflags
clang_asan_cflags = (" -fsanitize=address"
+ " -mno-omit-leaf-frame-pointer"
+ " -fno-omit-frame-pointer"
+ " -fno-optimize-sibling-calls"
+ " -g"
- + bits_cflag)
+ + target_cflags)
clang_asan_cxxflags = " --driver-mode=g++" + clang_asan_cflags
-config.substitutions.append( ("%clang ", " " + config.clang + bits_cflag + " "))
-config.substitutions.append( ("%clangxx ", (" " + config.clang +
+
+if config.android == "TRUE":
+ config.available_features.add('android')
+ clang_wrapper = os.path.join(config.asan_source_dir, "lit_tests",
+ "android_commands", "android_compile.py") + " "
+else:
+ clang_wrapper = ""
+
+config.substitutions.append( ("%clang ", " " + clang_wrapper + config.clang + target_cflags + " "))
+config.substitutions.append( ("%clangxx ", (" " + clang_wrapper + config.clang +
" --driver-mode=g++" +
- bits_cflag + " ")) )
-config.substitutions.append( ("%clang_asan ", (" " + config.clang + " " +
+ target_cflags + " ")) )
+config.substitutions.append( ("%clang_asan ", (" " + clang_wrapper + config.clang + " " +
clang_asan_cflags + " ")) )
-config.substitutions.append( ("%clangxx_asan ", (" " + config.clang + " " +
+config.substitutions.append( ("%clangxx_asan ", (" " + clang_wrapper + config.clang + " " +
clang_asan_cxxflags + " ")) )
+
# Setup path to asan_symbolize.py script.
asan_source_dir = get_required_attr(config, "asan_source_dir")
asan_symbolize = os.path.join(asan_source_dir, "scripts", "asan_symbolize.py")
diff --git a/lib/lit.common.configured.in b/lib/lit.common.configured.in
index 558655cbb..bfed0424c 100644
--- a/lib/lit.common.configured.in
+++ b/lib/lit.common.configured.in
@@ -1,19 +1,24 @@
## Autogenerated by LLVM/Clang configuration.
# Do not edit!
+# Set attribute value if it is unset.
+def set_default(attr, value):
+ if not getattr(config, attr, None):
+ setattr(config, attr, value)
+
# Generic config options for all compiler-rt lit tests.
-config.target_triple = "@TARGET_TRIPLE@"
-config.host_arch = "@HOST_ARCH@"
-config.host_os = "@HOST_OS@"
-config.llvm_build_mode = "@LLVM_BUILD_MODE@"
-config.llvm_src_root = "@LLVM_SOURCE_DIR@"
-config.llvm_obj_root = "@LLVM_BINARY_DIR@"
-config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@"
-config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
-config.clang = "@LLVM_BINARY_DIR@/bin/clang"
-config.compiler_rt_arch = "@COMPILER_RT_SUPPORTED_ARCH@"
-config.python_executable = "@PYTHON_EXECUTABLE@"
-config.compiler_rt_debug = @COMPILER_RT_DEBUG_PYBOOL@
+set_default("target_triple", "@TARGET_TRIPLE@")
+set_default("host_arch", "@HOST_ARCH@")
+set_default("host_os", "@HOST_OS@")
+set_default("llvm_build_mode", "@LLVM_BUILD_MODE@")
+set_default("llvm_src_root", "@LLVM_SOURCE_DIR@")
+set_default("llvm_obj_root", "@LLVM_BINARY_DIR@")
+set_default("compiler_rt_src_root", "@COMPILER_RT_SOURCE_DIR@")
+set_default("llvm_tools_dir", "@LLVM_TOOLS_DIR@")
+set_default("clang", "@LLVM_BINARY_DIR@/bin/clang")
+set_default("compiler_rt_arch", "@COMPILER_RT_SUPPORTED_ARCH@")
+set_default("python_executable", "@PYTHON_EXECUTABLE@")
+set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@)
# LLVM tools dir can be passed in lit parameters, so try to
# apply substitution.