[compiler-rt] r252723 - [ASan] Enable optional ASan recovery.
Yury Gribov via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 11 03:59:39 PST 2015
Author: ygribov
Date: Wed Nov 11 05:59:38 2015
New Revision: 252723
URL: http://llvm.org/viewvc/llvm-project?rev=252723&view=rev
Log:
[ASan] Enable optional ASan recovery.
Differential Revision: http://reviews.llvm.org/D12318
Added:
compiler-rt/trunk/test/asan/TestCases/Linux/halt_on_error-torture.cc
compiler-rt/trunk/test/asan/TestCases/halt_on_error-1.c
Modified:
compiler-rt/trunk/lib/asan/asan_flags.inc
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/asan_interface_internal.h
compiler-rt/trunk/lib/asan/asan_report.cc
compiler-rt/trunk/lib/asan/asan_report.h
compiler-rt/trunk/lib/asan/asan_rtl.cc
compiler-rt/trunk/test/asan/TestCases/Darwin/interface_symbols_darwin.c
compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c
Modified: compiler-rt/trunk/lib/asan/asan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.inc?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.inc (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.inc Wed Nov 11 05:59:38 2015
@@ -134,3 +134,6 @@ ASAN_FLAG(int, detect_odr_violation, 2,
ASAN_FLAG(bool, dump_instruction_bytes, false,
"If true, dump 16 bytes starting at the instruction that caused SEGV")
ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
+ASAN_FLAG(bool, halt_on_error, true,
+ "Crash the program after printing the first error report "
+ "(WARNING: USE AT YOUR OWN RISK!)")
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Wed Nov 11 05:59:38 2015
@@ -75,7 +75,7 @@ struct AsanInterceptorContext {
} \
if (!suppressed) { \
GET_CURRENT_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, __bad, isWrite, __size, 0); \
+ ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false);\
} \
} \
} while (0)
Modified: compiler-rt/trunk/lib/asan/asan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interface_internal.h?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interface_internal.h Wed Nov 11 05:59:38 2015
@@ -167,6 +167,19 @@ extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN(uptr p, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN(uptr p, uptr size);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uptr p, uptr size);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uptr p, uptr size);
+
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load1(uptr p, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load2(uptr p, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp);
Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Wed Nov 11 05:59:38 2015
@@ -622,41 +622,56 @@ void DescribeThread(AsanThreadContext *c
// immediately after printing error report.
class ScopedInErrorReport {
public:
- explicit ScopedInErrorReport(ReportData *report = nullptr) {
- static atomic_uint32_t num_calls;
- static u32 reporting_thread_tid;
- if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
+ explicit ScopedInErrorReport(ReportData *report = nullptr,
+ bool fatal = false) {
+ halt_on_error_ = fatal || flags()->halt_on_error;
+
+ if (lock_.TryLock()) {
+ StartReporting(report);
+ return;
+ }
+
+ // ASan found two bugs in different threads simultaneously.
+
+ u32 current_tid = GetCurrentTidOrInvalid();
+ if (current_tid == reporting_thread_tid_ || current_tid == kInvalidTid) {
+ // This is either asynch signal or nested error during error reporting.
+ // Fail fast to avoid deadlocks.
+
+ // Can't use Report() here because of potential deadlocks
+ // in nested signal handlers.
+ const char msg[] = "AddressSanitizer: nested bug in the same thread, "
+ "aborting.\n";
+ WriteToFile(kStderrFd, msg, sizeof(msg));
+
+ internal__exit(common_flags()->exitcode);
+ }
+
+ if (halt_on_error_) {
// Do not print more than one report, otherwise they will mix up.
// Error reporting functions shouldn't return at this situation, as
- // they are defined as no-return.
+ // they are effectively no-returns.
+
Report("AddressSanitizer: while reporting a bug found another one. "
- "Ignoring.\n");
- u32 current_tid = GetCurrentTidOrInvalid();
- if (current_tid != reporting_thread_tid) {
- // ASan found two bugs in different threads simultaneously. Sleep
- // long enough to make sure that the thread which started to print
- // an error report will finish doing it.
- SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
- }
+ "Ignoring.\n");
+
+ // Sleep long enough to make sure that the thread which started
+ // to print an error report will finish doing it.
+ SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
+
// If we're still not dead for some reason, use raw _exit() instead of
// Die() to bypass any additional checks.
internal__exit(common_flags()->exitcode);
+ } else {
+ // The other thread will eventually finish reporting
+ // so it's safe to wait
+ lock_.Lock();
}
- if (report) report_data = *report;
- report_happened = true;
- ASAN_ON_ERROR();
- // Make sure the registry and sanitizer report mutexes are locked while
- // we're printing an error report.
- // We can lock them only here to avoid self-deadlock in case of
- // recursive reports.
- asanThreadRegistry().Lock();
- CommonSanitizerReportMutex.Lock();
- reporting_thread_tid = GetCurrentTidOrInvalid();
- Printf("===================================================="
- "=============\n");
+
+ StartReporting(report);
}
- // Destructor is NORETURN, as functions that report errors are.
- NORETURN ~ScopedInErrorReport() {
+
+ ~ScopedInErrorReport() {
// Make sure the current thread is announced.
DescribeThread(GetCurrentThread());
// We may want to grab this lock again when printing stats.
@@ -667,11 +682,39 @@ class ScopedInErrorReport {
if (error_report_callback) {
error_report_callback(error_message_buffer);
}
- Report("ABORTING\n");
- Die();
+ CommonSanitizerReportMutex.Unlock();
+ reporting_thread_tid_ = kInvalidTid;
+ lock_.Unlock();
+ if (halt_on_error_) {
+ Report("ABORTING\n");
+ Die();
+ }
}
+
+ private:
+ void StartReporting(ReportData *report) {
+ if (report) report_data = *report;
+ report_happened = true;
+ ASAN_ON_ERROR();
+ // Make sure the registry and sanitizer report mutexes are locked while
+ // we're printing an error report.
+ // We can lock them only here to avoid self-deadlock in case of
+ // recursive reports.
+ asanThreadRegistry().Lock();
+ CommonSanitizerReportMutex.Lock();
+ reporting_thread_tid_ = GetCurrentTidOrInvalid();
+ Printf("===================================================="
+ "=============\n");
+ }
+
+ static StaticSpinMutex lock_;
+ static u32 reporting_thread_tid_;
+ bool halt_on_error_;
};
+StaticSpinMutex ScopedInErrorReport::lock_;
+u32 ScopedInErrorReport::reporting_thread_tid_;
+
void ReportStackOverflow(const SignalContext &sig) {
ScopedInErrorReport in_report;
Decorator d;
@@ -688,7 +731,7 @@ void ReportStackOverflow(const SignalCon
}
void ReportDeadlySignal(const char *description, const SignalContext &sig) {
- ScopedInErrorReport in_report;
+ ScopedInErrorReport in_report(/*report*/nullptr, /*fatal*/true);
Decorator d;
Printf("%s", d.Warning());
Report(
@@ -1034,7 +1077,7 @@ void __asan_report_error(uptr pc, uptr b
ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size,
bug_descr };
- ScopedInErrorReport in_report(&report);
+ ScopedInErrorReport in_report(&report, fatal);
Decorator d;
Printf("%s", d.Warning());
@@ -1060,6 +1103,18 @@ void __asan_report_error(uptr pc, uptr b
PrintShadowMemoryForAddress(addr);
}
+} // namespace __asan
+
+// --------------------------- Interface --------------------- {{{1
+using namespace __asan; // NOLINT
+
+void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
+ uptr access_size, u32 exp) {
+ ENABLE_FRAME_POINTER;
+ bool fatal = flags()->halt_on_error;
+ ReportGenericError(pc, bp, sp, addr, is_write, access_size, exp, fatal);
+}
+
void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
error_report_callback = callback;
if (callback) {
Modified: compiler-rt/trunk/lib/asan/asan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Wed Nov 11 05:59:38 2015
@@ -49,45 +49,41 @@ bool DescribeAddressIfStack(uptr addr, u
void DescribeThread(AsanThreadContext *context);
// Different kinds of error reports.
-void NORETURN ReportStackOverflow(const SignalContext &sig);
-void NORETURN ReportDeadlySignal(const char* description,
- const SignalContext &sig);
-void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
- BufferedStackTrace *free_stack);
-void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
-void NORETURN ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
-void NORETURN ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
- AllocType alloc_type,
- AllocType dealloc_type);
-void NORETURN
- ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
-void NORETURN
- ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
- BufferedStackTrace *stack);
-void NORETURN
- ReportStringFunctionMemoryRangesOverlap(const char *function,
- const char *offset1, uptr length1,
- const char *offset2, uptr length2,
- BufferedStackTrace *stack);
-void NORETURN ReportStringFunctionSizeOverflow(uptr offset, uptr size,
- BufferedStackTrace *stack);
-void NORETURN
- ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
- uptr old_mid, uptr new_mid,
- BufferedStackTrace *stack);
+void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
+ uptr access_size, u32 exp, bool fatal);
+void ReportStackOverflow(const SignalContext &sig);
+void ReportDeadlySignal(const char *description, const SignalContext &sig);
+void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
+ BufferedStackTrace *free_stack);
+void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
+void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
+void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
+ AllocType alloc_type,
+ AllocType dealloc_type);
+void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
+void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
+ BufferedStackTrace *stack);
+void ReportStringFunctionMemoryRangesOverlap(const char *function,
+ const char *offset1, uptr length1,
+ const char *offset2, uptr length2,
+ BufferedStackTrace *stack);
+void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
+ BufferedStackTrace *stack);
+void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
+ uptr old_mid, uptr new_mid,
+ BufferedStackTrace *stack);
-void NORETURN
-ReportODRViolation(const __asan_global *g1, u32 stack_id1,
- const __asan_global *g2, u32 stack_id2);
+void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
+ const __asan_global *g2, u32 stack_id2);
// Mac-specific errors and warnings.
void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name,
BufferedStackTrace *stack);
-void NORETURN ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
- const char *zone_name,
- BufferedStackTrace *stack);
-void NORETURN ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
- const char *zone_name,
- BufferedStackTrace *stack);
+void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
+ const char *zone_name,
+ BufferedStackTrace *stack);
+void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
+ const char *zone_name,
+ BufferedStackTrace *stack);
} // namespace __asan
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Nov 11 05:59:38 2015
@@ -113,13 +113,18 @@ static void OnLowLevelAllocate(uptr ptr,
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_ ## type ## size(uptr addr) { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, 0); \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
} \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, exp); \
-}
+ ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
+} \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## size ## _noabort(uptr addr) { \
+ GET_CALLER_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
+} \
ASAN_REPORT_ERROR(load, false, 1)
ASAN_REPORT_ERROR(load, false, 2)
@@ -132,22 +137,27 @@ ASAN_REPORT_ERROR(store, true, 4)
ASAN_REPORT_ERROR(store, true, 8)
ASAN_REPORT_ERROR(store, true, 16)
-#define ASAN_REPORT_ERROR_N(type, is_write) \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
- GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, 0); \
-} \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+#define ASAN_REPORT_ERROR_N(type, is_write) \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
+ GET_CALLER_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
+} \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, exp); \
-}
+ ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
+} \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
+ GET_CALLER_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
+} \
ASAN_REPORT_ERROR_N(load, false)
ASAN_REPORT_ERROR_N(store, true)
-#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg) \
+#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
uptr sp = MEM_TO_SHADOW(addr); \
uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
: *reinterpret_cast<u16 *>(sp); \
@@ -159,7 +169,8 @@ ASAN_REPORT_ERROR_N(store, true)
*__asan_test_only_reported_buggy_pointer = addr; \
} else { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, exp_arg); \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, \
+ fatal); \
} \
} \
}
@@ -167,12 +178,16 @@ ASAN_REPORT_ERROR_N(store, true)
#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_##type##size(uptr addr) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0) \
+ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \
} \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_exp_##type##size(uptr addr, u32 exp) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp) \
- }
+ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \
+ } \
+ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+ void __asan_##type##size ## _noabort(uptr addr) { \
+ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \
+ } \
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
@@ -190,7 +205,7 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_loadN(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, false, size, 0);
+ ReportGenericError(pc, bp, sp, addr, false, size, 0, true);
}
}
@@ -199,7 +214,16 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, false, size, exp);
+ ReportGenericError(pc, bp, sp, addr, false, size, exp, true);
+ }
+}
+
+extern "C"
+NOINLINE INTERFACE_ATTRIBUTE
+void __asan_loadN_noabort(uptr addr, uptr size) {
+ if (__asan_region_is_poisoned(addr, size)) {
+ GET_CALLER_PC_BP_SP;
+ ReportGenericError(pc, bp, sp, addr, false, size, 0, false);
}
}
@@ -208,7 +232,7 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_storeN(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, true, size, 0);
+ ReportGenericError(pc, bp, sp, addr, true, size, 0, true);
}
}
@@ -217,7 +241,16 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, true, size, exp);
+ ReportGenericError(pc, bp, sp, addr, true, size, exp, true);
+ }
+}
+
+extern "C"
+NOINLINE INTERFACE_ATTRIBUTE
+void __asan_storeN_noabort(uptr addr, uptr size) {
+ if (__asan_region_is_poisoned(addr, size)) {
+ GET_CALLER_PC_BP_SP;
+ ReportGenericError(pc, bp, sp, addr, true, size, 0, false);
}
}
Modified: compiler-rt/trunk/test/asan/TestCases/Darwin/interface_symbols_darwin.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Darwin/interface_symbols_darwin.c?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Darwin/interface_symbols_darwin.c (original)
+++ compiler-rt/trunk/test/asan/TestCases/Darwin/interface_symbols_darwin.c Wed Nov 11 05:59:38 2015
@@ -29,6 +29,18 @@
// RUN: echo __asan_report_store16 >> %t.interface
// RUN: echo __asan_report_load_n >> %t.interface
// RUN: echo __asan_report_store_n >> %t.interface
+// RUN: echo __asan_report_load1_noabort >> %t.interface
+// RUN: echo __asan_report_load2_noabort >> %t.interface
+// RUN: echo __asan_report_load4_noabort >> %t.interface
+// RUN: echo __asan_report_load8_noabort >> %t.interface
+// RUN: echo __asan_report_load16_noabort >> %t.interface
+// RUN: echo __asan_report_store1_noabort >> %t.interface
+// RUN: echo __asan_report_store2_noabort >> %t.interface
+// RUN: echo __asan_report_store4_noabort >> %t.interface
+// RUN: echo __asan_report_store8_noabort >> %t.interface
+// RUN: echo __asan_report_store16_noabort >> %t.interface
+// RUN: echo __asan_report_load_n_noabort >> %t.interface
+// RUN: echo __asan_report_store_n_noabort >> %t.interface
// RUN: echo __asan_report_exp_load1 >> %t.interface
// RUN: echo __asan_report_exp_load2 >> %t.interface
// RUN: echo __asan_report_exp_load4 >> %t.interface
Added: compiler-rt/trunk/test/asan/TestCases/Linux/halt_on_error-torture.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/halt_on_error-torture.cc?rev=252723&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/halt_on_error-torture.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/halt_on_error-torture.cc Wed Nov 11 05:59:38 2015
@@ -0,0 +1,79 @@
+// Stress test recovery mode with many threads.
+//
+// RUN: %clangxx_asan -fsanitize-recover=address %s -o %t
+//
+// RUN: env ASAN_OPTIONS=halt_on_error=false:max_errors=1000 %run %t 1 10 >1.txt 2>&1
+// RUN: FileCheck %s < 1.txt
+// RUN: [ $(wc -l < 1.txt) -gt 1 ]
+//
+// RUN: env ASAN_OPTIONS=halt_on_error=false:max_errors=1000 %run %t 10 20 >10.txt 2>&1
+// RUN: FileCheck %s < 10.txt
+// This one is racy although very unlikely to fail:
+// RUN: [ $(wc -l < 10.txt) -gt 1 ]
+// Collisions are highly unlikely but still possible so we need the alternative:
+// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
+//
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <sanitizer/asan_interface.h>
+
+size_t nthreads = 10;
+size_t niter = 10;
+
+void *run(void *arg) {
+ unsigned seed = (unsigned)(size_t)arg;
+
+ volatile char tmp[2];
+ __asan_poison_memory_region(&tmp, sizeof(tmp));
+
+ for (size_t i = 0; i < niter; ++i) {
+ struct timespec delay = { 0, rand_r(&seed) * 1000000 };
+ nanosleep(&delay, 0);
+
+ // Expect error collisions here
+ // CHECK: AddressSanitizer: use-after-poison
+ volatile int idx = 0;
+ tmp[idx] = 0;
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 3) {
+ fprintf(stderr, "Syntax: %s nthreads niter\n", argv[0]);
+ exit(1);
+ }
+
+ nthreads = (size_t)strtoul(argv[1], 0, 0);
+ niter = (size_t)strtoul(argv[2], 0, 0);
+
+ pthread_t *tids = new pthread_t[nthreads];
+
+ for (size_t i = 0; i < nthreads; ++i) {
+ if (0 != pthread_create(&tids[i], 0, run, (void *)i)) {
+ fprintf(stderr, "Failed to create thread\n");
+ exit(1);
+ }
+ }
+
+ for (size_t i = 0; i < nthreads; ++i) {
+ if (0 != pthread_join(tids[i], 0)) {
+ fprintf(stderr, "Failed to join thread\n");
+ exit(1);
+ }
+ }
+
+ // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting
+ // CHECK-NO-COLLISION: All threads terminated
+ printf("All threads terminated\n");
+
+ delete [] tids;
+
+ return 0;
+}
Modified: compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c?rev=252723&r1=252722&r2=252723&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c Wed Nov 11 05:59:38 2015
@@ -24,6 +24,18 @@
// RUN: echo __asan_report_store16 >> %t.interface
// RUN: echo __asan_report_load_n >> %t.interface
// RUN: echo __asan_report_store_n >> %t.interface
+// RUN: echo __asan_report_load1_noabort >> %t.interface
+// RUN: echo __asan_report_load2_noabort >> %t.interface
+// RUN: echo __asan_report_load4_noabort >> %t.interface
+// RUN: echo __asan_report_load8_noabort >> %t.interface
+// RUN: echo __asan_report_load16_noabort >> %t.interface
+// RUN: echo __asan_report_store1_noabort >> %t.interface
+// RUN: echo __asan_report_store2_noabort >> %t.interface
+// RUN: echo __asan_report_store4_noabort >> %t.interface
+// RUN: echo __asan_report_store8_noabort >> %t.interface
+// RUN: echo __asan_report_store16_noabort >> %t.interface
+// RUN: echo __asan_report_load_n_noabort >> %t.interface
+// RUN: echo __asan_report_store_n_noabort >> %t.interface
// RUN: echo __asan_report_exp_load1 >> %t.interface
// RUN: echo __asan_report_exp_load2 >> %t.interface
// RUN: echo __asan_report_exp_load4 >> %t.interface
Added: compiler-rt/trunk/test/asan/TestCases/halt_on_error-1.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/halt_on_error-1.c?rev=252723&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/halt_on_error-1.c (added)
+++ compiler-rt/trunk/test/asan/TestCases/halt_on_error-1.c Wed Nov 11 05:59:38 2015
@@ -0,0 +1,29 @@
+// Test recovery mode.
+//
+// RUN: %clang_asan -fsanitize-recover=address %s -o %t
+//
+// RUN: env not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:halt_on_error=true not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix CHECK-RECOVER
+
+#include <string.h>
+
+volatile int ten = 10;
+
+int main() {
+ char x[10];
+ // CHECK: WRITE of size 11
+ // CHECK-RECOVER: WRITE of size 11
+ memset(x, 0, 11);
+ // CHECK-NOT: READ of size 1
+ // CHECK-RECOVER: READ of size 1
+ volatile int res = x[ten];
+ // CHECK-NOT: WRITE of size 1
+ // CHECK-RECOVER: WRITE of size 1
+ x[ten] = res + 3;
+ // CHECK-NOT: READ of size 1
+ // CHECK-RECOVER: READ of size 1
+ res = x[ten];
+ return 0;
+}
+
More information about the llvm-commits
mailing list