forked from OSchip/llvm-project
Enable LSAN for Android
Make use of the newly added thread-properties API (available since 31). Differential Revision: https://reviews.llvm.org/D85927
This commit is contained in:
parent
62e2ac6461
commit
a2291a58bf
|
@ -681,7 +681,7 @@ else()
|
|||
endif()
|
||||
|
||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND
|
||||
OS_NAME MATCHES "Darwin|Linux|NetBSD|Fuchsia")
|
||||
OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|Fuchsia")
|
||||
set(COMPILER_RT_HAS_LSAN TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_LSAN FALSE)
|
||||
|
|
|
@ -86,6 +86,8 @@ append_rtti_flag(OFF ASAN_CFLAGS)
|
|||
set(ASAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
|
||||
|
||||
if(ANDROID)
|
||||
list(APPEND ASAN_CFLAGS -fno-emulated-tls)
|
||||
list(APPEND ASAN_DYNAMIC_LINK_FLAGS -fuse-ld=lld)
|
||||
# Put most Sanitizer shared libraries in the global group. For more details, see
|
||||
# android-changes-for-ndk-developers.md#changes-to-library-search-order
|
||||
if (COMPILER_RT_HAS_Z_GLOBAL)
|
||||
|
@ -232,7 +234,9 @@ else()
|
|||
-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
|
||||
# The Solaris 11.4 linker supports a subset of GNU ld version scripts,
|
||||
# but requires a special option to enable it.
|
||||
if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
|
||||
# This is used/compatible with ANDROID because we force `lld` on ANDROID (line 90).
|
||||
# Therefore we don't want to add it for ANDROID.
|
||||
if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT AND NOT ANDROID)
|
||||
list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
|
||||
endif()
|
||||
set_property(SOURCE
|
||||
|
|
|
@ -91,6 +91,7 @@ if(APPLE)
|
|||
endif()
|
||||
if(ANDROID)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -pie)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -fuse-ld=lld)
|
||||
endif()
|
||||
|
||||
set(ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS
|
||||
|
@ -288,6 +289,7 @@ if(ANDROID)
|
|||
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
|
||||
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
|
||||
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
|
||||
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
|
||||
$<TARGET_OBJECTS:RTUbsan.${arch}>
|
||||
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
|
||||
${COMPILER_RT_GTEST_SOURCE}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
include_directories(..)
|
||||
|
||||
set(LSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
|
||||
set(LSAN_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
|
||||
append_rtti_flag(OFF LSAN_CFLAGS)
|
||||
|
||||
set(LSAN_COMMON_SOURCES
|
||||
|
@ -33,6 +34,11 @@ set(LSAN_HEADERS
|
|||
|
||||
set(LSAN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(ANDROID)
|
||||
list(APPEND LSAN_CFLAGS -fno-emulated-tls)
|
||||
list(APPEND LSAN_LINK_FLAGS -fuse-ld=lld)
|
||||
endif()
|
||||
|
||||
add_compiler_rt_object_libraries(RTLSanCommon
|
||||
OS ${SANITIZER_COMMON_SUPPORTED_OS}
|
||||
ARCHS ${LSAN_COMMON_SUPPORTED_ARCH}
|
||||
|
@ -61,7 +67,7 @@ if(COMPILER_RT_HAS_LSAN)
|
|||
RTSanitizerCommonCoverage
|
||||
RTSanitizerCommonSymbolizer
|
||||
CFLAGS ${LSAN_CFLAGS}
|
||||
LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
LINK_FLAGS ${LSAN_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
LINK_LIBS ${LSAN_LINK_LIBS}
|
||||
PARENT_TARGET lsan)
|
||||
else()
|
||||
|
@ -78,6 +84,7 @@ if(COMPILER_RT_HAS_LSAN)
|
|||
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
|
||||
ADDITIONAL_HEADERS ${LSAN_HEADERS}
|
||||
CFLAGS ${LSAN_CFLAGS}
|
||||
LINK_FLAGS ${LSAN_LINK_FLAGS}
|
||||
PARENT_TARGET lsan)
|
||||
endforeach()
|
||||
endif()
|
||||
|
|
|
@ -71,17 +71,17 @@ static const char kSuppressionLeak[] = "leak";
|
|||
static const char *kSuppressionTypes[] = { kSuppressionLeak };
|
||||
static const char kStdSuppressions[] =
|
||||
#if SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
|
||||
// For more details refer to the SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
|
||||
// definition.
|
||||
"leak:*pthread_exit*\n"
|
||||
// For more details refer to the SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
|
||||
// definition.
|
||||
"leak:*pthread_exit*\n"
|
||||
#endif // SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
|
||||
#if SANITIZER_MAC
|
||||
// For Darwin and os_log/os_trace: https://reviews.llvm.org/D35173
|
||||
"leak:*_os_trace*\n"
|
||||
// For Darwin and os_log/os_trace: https://reviews.llvm.org/D35173
|
||||
"leak:*_os_trace*\n"
|
||||
#endif
|
||||
// TLS leak in some glibc versions, described in
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=12650.
|
||||
"leak:*tls_get_addr*\n";
|
||||
// TLS leak in some glibc versions, described in
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=12650.
|
||||
"leak:*tls_get_addr*\n";
|
||||
|
||||
void InitializeSuppressions() {
|
||||
CHECK_EQ(nullptr, suppression_ctx);
|
||||
|
@ -294,6 +294,22 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
|
|||
kReachable);
|
||||
}
|
||||
}
|
||||
#if SANITIZER_ANDROID
|
||||
if (HAS_ANDROID_THREAD_PROPERTIES_API) {
|
||||
auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/,
|
||||
void *arg) -> void {
|
||||
ScanRangeForPointers(reinterpret_cast<uptr>(dtls_begin),
|
||||
reinterpret_cast<uptr>(dtls_end),
|
||||
reinterpret_cast<Frontier *>(arg), "DTLS",
|
||||
kReachable);
|
||||
};
|
||||
|
||||
// FIXME: There might be a race-condition here (and in Bionic) if the
|
||||
// thread is suspended in the middle of updating its DTLS. IOWs, we
|
||||
// could scan already freed memory. (probably fine for now)
|
||||
__libc_iterate_dynamic_tls(os_id, cb, frontier);
|
||||
}
|
||||
#else
|
||||
if (dtls && !DTLSInDestruction(dtls)) {
|
||||
for (uptr j = 0; j < dtls->dtv_size; ++j) {
|
||||
uptr dtls_beg = dtls->dtv[j].beg;
|
||||
|
@ -309,6 +325,7 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
|
|||
// this and continue.
|
||||
LOG_THREADS("Thread %d has DTLS under destruction.\n", os_id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -575,8 +592,16 @@ static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
|
|||
}
|
||||
|
||||
static bool CheckForLeaks() {
|
||||
#if SANITIZER_ANDROID
|
||||
// Presence of the ThreadProperties API implies the presence of
|
||||
// TLS support, which is required for calling __lsan_is_turned_off().
|
||||
// Therefore, this check must preceed that.
|
||||
if (!HAS_ANDROID_THREAD_PROPERTIES_API)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (&__lsan_is_turned_off && __lsan_is_turned_off())
|
||||
return false;
|
||||
return false;
|
||||
EnsureMainThreadIDIsCorrect();
|
||||
CheckForLeaksParam param;
|
||||
LockStuffAndStopTheWorld(CheckForLeaksCallback, ¶m);
|
||||
|
|
|
@ -29,16 +29,13 @@
|
|||
// To enable LeakSanitizer on a new architecture, one needs to implement the
|
||||
// internal_clone function as well as (probably) adjust the TLS machinery for
|
||||
// the new architecture inside the sanitizer library.
|
||||
#if (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC) && \
|
||||
(SANITIZER_WORDSIZE == 64) && \
|
||||
#if (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \
|
||||
(defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
|
||||
defined(__powerpc64__) || defined(__s390x__))
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#elif defined(__i386__) && \
|
||||
(SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC)
|
||||
#elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_MAC)
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#elif defined(__arm__) && \
|
||||
SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
#elif defined(__arm__) && SANITIZER_LINUX
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
|
|
|
@ -41,9 +41,28 @@ static bool IsLinker(const LoadedModule& module) {
|
|||
|
||||
__attribute__((tls_model("initial-exec")))
|
||||
THREADLOCAL int disable_counter;
|
||||
bool DisabledInThisThread() { return disable_counter > 0; }
|
||||
void DisableInThisThread() { disable_counter++; }
|
||||
bool DisabledInThisThread() {
|
||||
#if SANITIZER_ANDROID
|
||||
// LSAN is only enabled with Android-S and up.
|
||||
if (!HAS_ANDROID_THREAD_PROPERTIES_API)
|
||||
return true;
|
||||
#endif
|
||||
return disable_counter > 0;
|
||||
}
|
||||
void DisableInThisThread() {
|
||||
#if SANITIZER_ANDROID
|
||||
// LSAN is only enabled with Android-S and up.
|
||||
if (!HAS_ANDROID_THREAD_PROPERTIES_API)
|
||||
return;
|
||||
#endif
|
||||
disable_counter++;
|
||||
}
|
||||
void EnableInThisThread() {
|
||||
#if SANITIZER_ANDROID
|
||||
// LSAN is only enabled with Android-S and up.
|
||||
if (!HAS_ANDROID_THREAD_PROPERTIES_API)
|
||||
return;
|
||||
#endif
|
||||
if (disable_counter == 0) {
|
||||
DisableCounterUnderflow();
|
||||
}
|
||||
|
@ -95,7 +114,15 @@ static int ProcessGlobalRegionsCallback(struct dl_phdr_info *info, size_t size,
|
|||
|
||||
// Scans global variables for heap pointers.
|
||||
void ProcessGlobalRegions(Frontier *frontier) {
|
||||
if (!flags()->use_globals) return;
|
||||
if (!flags()->use_globals) {
|
||||
#if SANITIZER_ANDROID
|
||||
// There are known malloc'ed global variables from libc[++] on Android.
|
||||
// If use_globals is turnt off, we could see leaks.
|
||||
// Issue a warning in case users turn it off by accident.
|
||||
Report("use_globals=0 on Android could lead to false reports.");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
dl_iterate_phdr(ProcessGlobalRegionsCallback, frontier);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,8 +104,9 @@
|
|||
//
|
||||
// FIXME: do we have anything like this on Mac?
|
||||
#ifndef SANITIZER_CAN_USE_PREINIT_ARRAY
|
||||
#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_OPENBSD || \
|
||||
SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC)
|
||||
#if (SANITIZER_LINUX || SANITIZER_OPENBSD || SANITIZER_FUCHSIA || \
|
||||
SANITIZER_NETBSD) && \
|
||||
!defined(PIC)
|
||||
#define SANITIZER_CAN_USE_PREINIT_ARRAY 1
|
||||
// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld.
|
||||
// FIXME: Check for those conditions.
|
||||
|
|
|
@ -154,6 +154,16 @@ ALWAYS_INLINE uptr *get_android_tls_ptr() {
|
|||
return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]);
|
||||
}
|
||||
|
||||
// Bionic provides this API since 31.
|
||||
extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_get_static_tls_bounds(void **,
|
||||
void **);
|
||||
extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_iterate_dynamic_tls(
|
||||
pid_t, void (*cb)(void *, void *, uptr, void *), void *);
|
||||
|
||||
#define HAS_ANDROID_THREAD_PROPERTIES_API (&__libc_iterate_dynamic_tls != 0)
|
||||
|
||||
#else
|
||||
#define HAS_ANDROID_THREAD_PROPERTIES_API (0)
|
||||
#endif // SANITIZER_ANDROID
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
|
|
@ -460,7 +460,19 @@ int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) {
|
|||
|
||||
#if !SANITIZER_GO
|
||||
static void GetTls(uptr *addr, uptr *size) {
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
#if SANITIZER_ANDROID
|
||||
if (HAS_ANDROID_THREAD_PROPERTIES_API) {
|
||||
void *start_addr;
|
||||
void *end_addr;
|
||||
__libc_get_static_tls_bounds(&start_addr, &end_addr);
|
||||
*addr = reinterpret_cast<uptr>(start_addr);
|
||||
*size =
|
||||
reinterpret_cast<uptr>(end_addr) - reinterpret_cast<uptr>(start_addr);
|
||||
} else {
|
||||
*addr = 0;
|
||||
*size = 0;
|
||||
}
|
||||
#elif SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__s390__)
|
||||
*addr = ThreadSelf();
|
||||
*size = GetTlsSize();
|
||||
|
@ -504,9 +516,6 @@ static void GetTls(uptr *addr, uptr *size) {
|
|||
#elif SANITIZER_OPENBSD
|
||||
*addr = 0;
|
||||
*size = 0;
|
||||
#elif SANITIZER_ANDROID
|
||||
*addr = 0;
|
||||
*size = 0;
|
||||
#elif SANITIZER_SOLARIS
|
||||
// FIXME
|
||||
*addr = 0;
|
||||
|
|
|
@ -504,14 +504,15 @@
|
|||
#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \
|
||||
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
|
||||
SI_NOT_RTEMS && !SI_SOLARIS)
|
||||
#define SANITIZER_INTERCEPT_MEMALIGN \
|
||||
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_RTEMS)
|
||||
#define SANITIZER_INTERCEPT_MEMALIGN \
|
||||
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_RTEMS && \
|
||||
!SI_ANDROID)
|
||||
#define SANITIZER_INTERCEPT_PVALLOC \
|
||||
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
|
||||
SI_NOT_RTEMS && !SI_SOLARIS)
|
||||
#define SANITIZER_INTERCEPT_CFREE \
|
||||
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
|
||||
SI_NOT_RTEMS && !SI_SOLARIS)
|
||||
SI_NOT_RTEMS && !SI_SOLARIS && !SI_ANDROID)
|
||||
#define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX
|
||||
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS)
|
||||
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE \
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
// RUN: %sancov print %t-dir/*.sancov 2>&1
|
||||
//
|
||||
// REQUIRES: leak-detection
|
||||
|
||||
// FIXME: sancov paths not work with adb
|
||||
// UNSUPPORTED: android
|
||||
int *g = new int;
|
||||
int main(int argc, char **argv) {
|
||||
g = 0;
|
||||
|
|
|
@ -209,10 +209,11 @@ if re.search('mthumb', config.target_cflags) is None:
|
|||
config.available_features.add('fast-unwinder-works')
|
||||
|
||||
# Turn on leak detection on 64-bit Linux.
|
||||
leak_detection_android = config.android and 'android-thread-properties-api' in config.available_features and (config.target_arch == 'x86_64' or config.target_arch == 'i386' or config.target_arch == 'i686' or config.target_arch == 'aarch64' )
|
||||
leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch == 'x86_64' or config.target_arch == 'i386')
|
||||
leak_detection_mac = (config.host_os == 'Darwin') and (config.target_arch == 'x86_64')
|
||||
leak_detection_netbsd = (config.host_os == 'NetBSD') and (config.target_arch in ['x86_64', 'i386'])
|
||||
if leak_detection_linux or leak_detection_mac or leak_detection_netbsd:
|
||||
if leak_detection_android or leak_detection_linux or leak_detection_mac or leak_detection_netbsd:
|
||||
config.available_features.add('leak-detection')
|
||||
|
||||
# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
|
||||
|
|
|
@ -61,6 +61,13 @@ if config.asan_shadow_scale != '':
|
|||
# BFD linker in 64-bit android toolchains fails to find libc++_shared.so, which
|
||||
# is a transitive shared library dependency (via asan runtime).
|
||||
if config.android:
|
||||
# These are needed for tests to upload/download temp files, such as
|
||||
# suppression-files, to device.
|
||||
config.substitutions.append( ('%device_rundir', "/data/local/tmp/Output") )
|
||||
# FIXME: May need to select specific device with `-s SERIAL`
|
||||
config.substitutions.append( ('%push_to_device', "adb push ") )
|
||||
config.substitutions.append( ('%pull_from_device', "adb pull ") )
|
||||
config.substitutions.append( ('%adb_shell ', "adb shell ") )
|
||||
# Prepend the flag so that it can be overridden.
|
||||
config.target_cflags = "-pie -fuse-ld=gold " + config.target_cflags
|
||||
if config.android_ndk_version < 19:
|
||||
|
@ -69,7 +76,11 @@ if config.android:
|
|||
# just contains a handful of ABI functions", which makes most C++ code fail
|
||||
# to link. In r19 and later we just use the default which is libc++.
|
||||
config.cxx_mode_flags.append('-stdlib=libstdc++')
|
||||
|
||||
else:
|
||||
config.substitutions.append( ('%device_rundir', "") )
|
||||
config.substitutions.append( ('%push_to_device', "echo ") )
|
||||
config.substitutions.append( ('%pull_from_device', "echo ") )
|
||||
config.substitutions.append( ('%adb_shell', "echo ") )
|
||||
config.environment = dict(os.environ)
|
||||
|
||||
# Clear some environment variables that might affect Clang.
|
||||
|
@ -341,10 +352,15 @@ if config.android:
|
|||
if config.android_serial:
|
||||
env['ANDROID_SERIAL'] = config.android_serial
|
||||
config.environment['ANDROID_SERIAL'] = config.android_serial
|
||||
|
||||
# Must use lld because Bionic's TLS layout is not compatible with the Gold convention.
|
||||
# The buildbot script will guarantee lld is built/included.
|
||||
# The check for `has_lld` somehow missed that it exists and always marked tests as "unsupported".
|
||||
config.use_lld = True
|
||||
config.has_lld = True
|
||||
adb = os.environ.get('ADB', 'adb')
|
||||
try:
|
||||
android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip()
|
||||
android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8")
|
||||
except (subprocess.CalledProcessError, OSError):
|
||||
lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb)
|
||||
try:
|
||||
|
@ -355,6 +371,8 @@ if config.android:
|
|||
config.available_features.add('android-26')
|
||||
if android_api_level >= 28:
|
||||
config.available_features.add('android-28')
|
||||
if android_api_level >= 31 or android_api_codename == 'S':
|
||||
config.available_features.add('android-thread-properties-api')
|
||||
|
||||
# Prepare the device.
|
||||
android_tmpdir = '/data/local/tmp/Output'
|
||||
|
@ -374,7 +392,7 @@ if config.host_os == 'Linux':
|
|||
from distutils.version import LooseVersion
|
||||
ver = LooseVersion(ver_line.split()[-1].decode())
|
||||
# 2.27 introduced some incompatibilities
|
||||
if ver >= LooseVersion("2.27"):
|
||||
if ver >= LooseVersion("2.27") and not config.android:
|
||||
config.available_features.add("glibc-2.27")
|
||||
|
||||
sancovcc_path = os.path.join(config.llvm_tools_dir, "sancov")
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// user-installed TSD destructors have finished running (since they may contain
|
||||
// additional cleanup tasks). LSan doesn't actually meet that goal 100%, but it
|
||||
// makes its best effort.
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0"
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0"
|
||||
// RUN: %clang_lsan %s -o %t
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE:use_tls=1 %run %t
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE:use_tls=0 not %run %t 2>&1 | FileCheck %s
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Regression test. Disabler should not depend on TSD validity.
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=1:use_ld_allocations=0"
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_tls=1:use_ld_allocations=0"
|
||||
// RUN: %clang_lsan %s -o %t
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE %run %t
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Check that if LSan finds that SP doesn't point into thread stack (e.g.
|
||||
// if swapcontext is used), LSan will not hit the guard page.
|
||||
// RUN: %clang_lsan %s -o %t && %run %t
|
||||
// Missing 'getcontext' and 'makecontext' on Android.
|
||||
// UNSUPPORTED: android
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
|
||||
// Good log_path.
|
||||
// RUN: rm -f %t.log.*
|
||||
// RUN: %env_lsan_opts="use_stacks=0:log_path='"%t.log"'" not %run %t > %t.out 2>&1
|
||||
// RUN: %adb_shell 'rm -f %t.log.*'
|
||||
// RUN: %env_lsan_opts="use_stacks=0:log_path='"%device_rundir/%t.log"'" not %run %t > %t.out 2>&1
|
||||
// adb-pull doesn't support wild cards so we need to rename the log file.
|
||||
// RUN: %adb_shell 'mv %device_rundir/%t.log.* %device_rundir/%t.log'
|
||||
// RUN: %pull_from_device %device_rundir/%t.log %t.log.ANDROID
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.*
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Test that dynamically allocated TLS space is included in the root set.
|
||||
|
||||
// This is known to be broken with glibc-2.27+
|
||||
// but it should pass with Bionic
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=37804
|
||||
// XFAIL: glibc-2.27
|
||||
|
||||
|
@ -10,7 +11,7 @@
|
|||
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t 2>&1
|
||||
// RUN: %env_lsan_opts="" %run %t 2>&1
|
||||
// UNSUPPORTED: i386-linux,arm,powerpc
|
||||
// UNSUPPORTED: arm,powerpc
|
||||
|
||||
#ifndef BUILD_DSO
|
||||
#include <assert.h>
|
||||
|
|
|
@ -19,7 +19,10 @@ int main() {
|
|||
int res;
|
||||
res = pthread_key_create(&key, NULL);
|
||||
assert(res == 0);
|
||||
#if !defined(__ANDROID__) && !defined(__BIONIC__)
|
||||
// Bionic doesn't have specific limit.
|
||||
assert(key < PTHREAD_KEY_2NDLEVEL_SIZE);
|
||||
#endif
|
||||
void *p = malloc(1337);
|
||||
res = pthread_setspecific(key, p);
|
||||
assert(res == 0);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Test for __lsan_disable() / __lsan_enable().
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0"
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_tls=0"
|
||||
// RUN: %clang_lsan %s -o %t
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Test for ScopedDisabler.
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0"
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_tls=0"
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Test for __lsan_ignore_object().
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0"
|
||||
// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_tls=0"
|
||||
// RUN: %clang_lsan %s -o %t
|
||||
// RUN: %env_lsan_opts=$LSAN_BASE not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// For 32 bit LSan it's pretty likely that large chunks are "reachable" from some
|
||||
// internal data structures (e.g. Glibc global data).
|
||||
// UNSUPPORTED: x86, arm
|
||||
// UNSUPPORTED: x86, arm, i686
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
// REQUIRES: strace
|
||||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: not strace -o /dev/null %run %t 2>&1 | FileCheck %s
|
||||
// FIXME: This technically works in practice but cannot be tested because the
|
||||
// fatal-error caused adb to failed. Could not be captured to stderr to lit-check.
|
||||
// XFAIL: android
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
|
||||
// RUN: rm -f %t.supp
|
||||
// RUN: touch %t.supp
|
||||
// RUN: %env_lsan_opts="$LSAN_BASE:suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s --check-prefix=NOSUPP
|
||||
// RUN: %push_to_device %t.supp %device_rundir/%t.supp
|
||||
// RUN: %env_lsan_opts="$LSAN_BASE:suppressions='%device_rundir/%t.supp'" not %run %t 2>&1 | FileCheck %s --check-prefix=NOSUPP
|
||||
|
||||
// RUN: echo "leak:*LSanTestLeakingFunc*" > %t.supp
|
||||
// RUN: %env_lsan_opts="$LSAN_BASE:suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: %push_to_device %t.supp %device_rundir/%t.supp
|
||||
// RUN: %env_lsan_opts="$LSAN_BASE:suppressions='%device_rundir/%t.supp'" not %run %t 2>&1 | FileCheck %s
|
||||
//
|
||||
// RUN: echo "leak:%t" > %t.supp
|
||||
// RUN: %env_lsan_opts="$LSAN_BASE:suppressions='%t.supp':symbolize=false" %run %t
|
||||
// RUN: %push_to_device %t.supp %device_rundir/%t.supp
|
||||
// RUN: %env_lsan_opts="$LSAN_BASE:suppressions='%device_rundir/%t.supp':symbolize=false" %run %t
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
// RUN: %clangxx_lsan %s -o %t
|
||||
// RUN: %env_lsan_opts= %run %t 2>&1
|
||||
// RUN: %env_lsan_opts= not %run %t foo 2>&1 | FileCheck %s
|
||||
// UNSUPPORTED: arm,powerpc64
|
||||
// Missing 'getcontext' and 'makecontext' on Android.
|
||||
// UNSUPPORTED: arm,powerpc64,android
|
||||
|
||||
#include "sanitizer_common/sanitizer_ucontext.h"
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -21,11 +21,10 @@ void *registers_thread_func(void *arg) {
|
|||
|
||||
// To store the pointer, choose a register which is unlikely to be reused by
|
||||
// a function call.
|
||||
#if defined(__i386__)
|
||||
asm ( "mov %0, %%esi"
|
||||
#if defined(__i386__) || defined(__i686__)
|
||||
asm("mov %0, %%edi"
|
||||
:
|
||||
: "r" (p)
|
||||
);
|
||||
: "r"(p));
|
||||
#elif defined(__x86_64__)
|
||||
asm ( "mov %0, %%r15"
|
||||
:
|
||||
|
@ -41,6 +40,12 @@ void *registers_thread_func(void *arg) {
|
|||
:
|
||||
: "r" (p)
|
||||
);
|
||||
#elif defined(__aarch64__)
|
||||
// x9-10are used. x11-12 are probably used.
|
||||
// So we pick x13 to be safe.
|
||||
asm("mov x13, %0"
|
||||
:
|
||||
: "r"(p));
|
||||
#elif defined(__powerpc__)
|
||||
asm ( "mr 30, %0"
|
||||
:
|
||||
|
|
|
@ -21,6 +21,7 @@ config.test_source_root = os.path.dirname(__file__)
|
|||
|
||||
# Choose between standalone and LSan+ASan modes.
|
||||
lsan_lit_test_mode = get_required_attr(config, 'lsan_lit_test_mode')
|
||||
|
||||
if lsan_lit_test_mode == "Standalone":
|
||||
config.name = "LeakSanitizer-Standalone"
|
||||
lsan_cflags = ["-fsanitize=leak"]
|
||||
|
@ -35,7 +36,8 @@ else:
|
|||
config.name += config.name_suffix
|
||||
|
||||
# Platform-specific default LSAN_OPTIONS for lit tests.
|
||||
default_lsan_opts = 'detect_leaks=1'
|
||||
default_common_opts_str = ':'.join(list(config.default_sanitizer_opts))
|
||||
default_lsan_opts = default_common_opts_str + ':detect_leaks=1'
|
||||
if config.host_os == 'Darwin':
|
||||
# On Darwin, we default to `abort_on_error=1`, which would make tests run
|
||||
# much slower. Let's override this and run lit tests with 'abort_on_error=0'.
|
||||
|
@ -53,6 +55,8 @@ if lit.util.which('strace'):
|
|||
config.available_features.add('strace')
|
||||
|
||||
clang_cflags = ["-O0", config.target_cflags] + config.debug_info_flags
|
||||
if config.android:
|
||||
clang_cflags = clang_cflags + ["-fno-emulated-tls"]
|
||||
clang_cxxflags = config.cxx_mode_flags + clang_cflags
|
||||
lsan_incdir = config.test_source_root + "/../"
|
||||
clang_lsan_cflags = clang_cflags + lsan_cflags + ["-I%s" % lsan_incdir]
|
||||
|
@ -76,6 +80,10 @@ supported_netbsd = config.host_os == 'NetBSD' and config.target_arch in ['x86_64
|
|||
if not (supported_linux or supported_darwin or supported_netbsd):
|
||||
config.unsupported = True
|
||||
|
||||
# Only run the tests on Android, if required API level is present.
|
||||
if config.android and 'android-thread-properties-api' not in config.available_features:
|
||||
config.unsupported = True
|
||||
|
||||
# Don't support Thumb due to broken fast unwinder
|
||||
if re.search('mthumb', config.target_cflags) is not None:
|
||||
config.unsupported = True
|
||||
|
|
Loading…
Reference in New Issue