diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-02-14 09:22:10 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-02-14 09:22:10 +0000 |
commit | 08c9d0bc3ac37d7d5def0318a1420e67cca53e41 (patch) | |
tree | d7a1020610e73102dc5e6342245e01fbb780c9db /lib | |
parent | 53aa4fda49f94920139300227786ac47c393f1ce (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.in | 12 | ||||
-rw-r--r-- | lib/asan/lit_tests/CMakeLists.txt | 59 | ||||
-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.py | 29 | ||||
-rwxr-xr-x | lib/asan/lit_tests/android_commands/android_compile.py | 36 | ||||
-rwxr-xr-x | lib/asan/lit_tests/android_commands/android_run.py | 34 | ||||
-rw-r--r-- | lib/asan/lit_tests/lit.cfg | 25 | ||||
-rw-r--r-- | lib/lit.common.configured.in | 29 |
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. |