forked from OSchip/llvm-project
ASAN activate/deactive controls thread_local_quarantine_size_kb option.
Summary: Bypass quarantine altogether when quarantine size is set ot zero. Also, relax atomic load/store of quarantine parameters, the release/acquire semantics is an overkill here. Reviewers: eugenis Subscribers: kubabrecka, llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D28586 llvm-svn: 291791
This commit is contained in:
parent
31c039ef2e
commit
c4427a3976
|
|
@ -77,12 +77,13 @@ static struct AsanDeactivatedFlags {
|
|||
|
||||
void Print() {
|
||||
Report(
|
||||
"quarantine_size_mb %d, max_redzone %d, poison_heap %d, "
|
||||
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
|
||||
"allocator_may_return_null %d, coverage %d, coverage_dir %s, "
|
||||
"allocator_release_to_os_interval_ms %d\n",
|
||||
allocator_options.quarantine_size_mb, allocator_options.max_redzone,
|
||||
poison_heap, malloc_context_size,
|
||||
"quarantine_size_mb %d, thread_local_quarantine_size_kb %d, "
|
||||
"max_redzone %d, poison_heap %d, malloc_context_size %d, "
|
||||
"alloc_dealloc_mismatch %d, allocator_may_return_null %d, coverage %d, "
|
||||
"coverage_dir %s, allocator_release_to_os_interval_ms %d\n",
|
||||
allocator_options.quarantine_size_mb,
|
||||
allocator_options.thread_local_quarantine_size_kb,
|
||||
allocator_options.max_redzone, poison_heap, malloc_context_size,
|
||||
allocator_options.alloc_dealloc_mismatch,
|
||||
allocator_options.may_return_null, coverage, coverage_dir,
|
||||
allocator_options.release_to_os_interval_ms);
|
||||
|
|
@ -109,6 +110,7 @@ void AsanDeactivate() {
|
|||
|
||||
AllocatorOptions disabled = asan_deactivated_flags.allocator_options;
|
||||
disabled.quarantine_size_mb = 0;
|
||||
disabled.thread_local_quarantine_size_kb = 0;
|
||||
disabled.min_redzone = 16; // Redzone must be at least 16 bytes long.
|
||||
disabled.max_redzone = 16;
|
||||
disabled.alloc_dealloc_mismatch = false;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
ASAN_ACTIVATION_FLAG(int, redzone)
|
||||
ASAN_ACTIVATION_FLAG(int, max_redzone)
|
||||
ASAN_ACTIVATION_FLAG(int, quarantine_size_mb)
|
||||
ASAN_ACTIVATION_FLAG(int, thread_local_quarantine_size_kb)
|
||||
ASAN_ACTIVATION_FLAG(bool, alloc_dealloc_mismatch)
|
||||
ASAN_ACTIVATION_FLAG(bool, poison_heap)
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,11 @@ void InitializeFlags() {
|
|||
(ASAN_LOW_MEMORY) ? 1 << 6 : FIRST_32_SECOND_64(1 << 8, 1 << 10);
|
||||
f->thread_local_quarantine_size_kb = kDefaultThreadLocalQuarantineSizeKb;
|
||||
}
|
||||
if (f->thread_local_quarantine_size_kb == 0 && f->quarantine_size_mb > 0) {
|
||||
Report("%s: thread_local_quarantine_size_kb can be set to 0 only when "
|
||||
"quarantine_size_mb is set to 0\n", SanitizerToolName);
|
||||
Die();
|
||||
}
|
||||
if (!f->replace_str && common_flags()->intercept_strlen) {
|
||||
Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
|
||||
"Use intercept_strlen=0 to disable it.");
|
||||
|
|
|
|||
|
|
@ -49,18 +49,31 @@ class Quarantine {
|
|||
}
|
||||
|
||||
void Init(uptr size, uptr cache_size) {
|
||||
atomic_store(&max_size_, size, memory_order_release);
|
||||
// Thread local quarantine size can be zero only when global quarantine size
|
||||
// is zero (it allows us to perform just one atomic read per Put() call).
|
||||
CHECK((size == 0 && cache_size == 0) || cache_size != 0);
|
||||
|
||||
atomic_store(&max_size_, size, memory_order_relaxed);
|
||||
atomic_store(&min_size_, size / 10 * 9,
|
||||
memory_order_release); // 90% of max size.
|
||||
max_cache_size_ = cache_size;
|
||||
memory_order_relaxed); // 90% of max size.
|
||||
atomic_store(&max_cache_size_, cache_size, memory_order_relaxed);
|
||||
}
|
||||
|
||||
uptr GetSize() const { return atomic_load(&max_size_, memory_order_acquire); }
|
||||
uptr GetCacheSize() const { return max_cache_size_; }
|
||||
uptr GetSize() const { return atomic_load(&max_size_, memory_order_relaxed); }
|
||||
uptr GetCacheSize() const {
|
||||
return atomic_load(&max_cache_size_, memory_order_relaxed);
|
||||
}
|
||||
|
||||
void Put(Cache *c, Callback cb, Node *ptr, uptr size) {
|
||||
uptr cache_size = GetCacheSize();
|
||||
if (cache_size) {
|
||||
c->Enqueue(cb, ptr, size);
|
||||
if (c->Size() > max_cache_size_)
|
||||
} else {
|
||||
// cache_size == 0 only when size == 0 (see Init).
|
||||
cb.Recycle(ptr);
|
||||
}
|
||||
// Check cache size anyway to accommodate for runtime cache_size change.
|
||||
if (c->Size() > cache_size)
|
||||
Drain(c, cb);
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +96,7 @@ class Quarantine {
|
|||
char pad0_[kCacheLineSize];
|
||||
atomic_uintptr_t max_size_;
|
||||
atomic_uintptr_t min_size_;
|
||||
uptr max_cache_size_;
|
||||
atomic_uintptr_t max_cache_size_;
|
||||
char pad1_[kCacheLineSize];
|
||||
SpinMutex cache_mutex_;
|
||||
SpinMutex recycle_mutex_;
|
||||
|
|
@ -92,7 +105,7 @@ class Quarantine {
|
|||
|
||||
void NOINLINE Recycle(Callback cb) {
|
||||
Cache tmp;
|
||||
uptr min_size = atomic_load(&min_size_, memory_order_acquire);
|
||||
uptr min_size = atomic_load(&min_size_, memory_order_relaxed);
|
||||
{
|
||||
SpinMutexLock l(&cache_mutex_);
|
||||
while (cache_.Size() > min_size) {
|
||||
|
|
@ -205,6 +218,7 @@ class QuarantineCache {
|
|||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_QUARANTINE_H
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
// RUN: FileCheck %s --check-prefix=CHECK-VALUE
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=64:quarantine_size_mb=64 %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --allow-empty --check-prefix=CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=64 %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-NO-LOCAL-CACHE-HUGE-OVERHEAD
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=0 %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-QUARANTINE-DISABLED
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=64 not %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-FOR-PARAMETER-ERROR
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -37,4 +39,5 @@ int main() {
|
|||
|
||||
// CHECK-VALUE: thread_local_quarantine_size_kb=256K
|
||||
// CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD-NOT: Heap size limit exceeded
|
||||
// CHECK-NO-LOCAL-CACHE-HUGE-OVERHEAD: Heap size limit exceeded
|
||||
// CHECK-QUARANTINE-DISABLED-NOT: Heap size limit exceeded
|
||||
// CHECK-FOR-PARAMETER-ERROR: thread_local_quarantine_size_kb can be set to 0 only when quarantine_size_mb is set to 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue