[compiler-rt] r224605 - [ASan] Introduce AllocatorOptions to configure allocator behavior.
Alexey Samsonov
vonosmas at gmail.com
Fri Dec 19 11:35:11 PST 2014
Author: samsonov
Date: Fri Dec 19 13:35:11 2014
New Revision: 224605
URL: http://llvm.org/viewvc/llvm-project?rev=224605&view=rev
Log:
[ASan] Introduce AllocatorOptions to configure allocator behavior.
Summary:
Reduce the dependency of allocator code on runtime flags. Instead,
pass a bunch of options that configure allocator behavior at
initialization or re-initialization. That would allow us to
cleaner modify allocator behavior during a program execution
when ASan is activated or de-activated.
Test Plan: regression test suite
Reviewers: kcc
Subscribers: llvm-commits, eugenis
Differential Revision: http://reviews.llvm.org/D6711
Modified:
compiler-rt/trunk/lib/asan/asan_activation.cc
compiler-rt/trunk/lib/asan/asan_allocator.cc
compiler-rt/trunk/lib/asan/asan_allocator.h
compiler-rt/trunk/lib/asan/asan_rtl.cc
Modified: compiler-rt/trunk/lib/asan/asan_activation.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_activation.cc?rev=224605&r1=224604&r2=224605&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_activation.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_activation.cc Fri Dec 19 13:35:11 2014
@@ -23,20 +23,14 @@
namespace __asan {
static struct AsanDeactivatedFlags {
- int quarantine_size;
- int max_redzone;
+ AllocatorOptions allocator_options;
int malloc_context_size;
bool poison_heap;
- bool alloc_dealloc_mismatch;
- bool allocator_may_return_null;
void CopyFrom(const Flags *f, const CommonFlags *cf) {
- quarantine_size = f->quarantine_size;
- max_redzone = f->max_redzone;
+ allocator_options.SetFrom(f, cf);
malloc_context_size = cf->malloc_context_size;
poison_heap = f->poison_heap;
- alloc_dealloc_mismatch = f->alloc_dealloc_mismatch;
- allocator_may_return_null = cf->allocator_may_return_null;
}
void OverrideFromActivationFlags() {
@@ -44,12 +38,14 @@ static struct AsanDeactivatedFlags {
CommonFlags cf;
// Copy the current activation flags.
- f.quarantine_size = quarantine_size;
- f.max_redzone = max_redzone;
+ f.quarantine_size = allocator_options.quarantine_size_mb << 20;
+ f.redzone = allocator_options.min_redzone;
+ f.max_redzone = allocator_options.max_redzone;
+ cf.allocator_may_return_null = allocator_options.may_return_null;
+ f.alloc_dealloc_mismatch = allocator_options.alloc_dealloc_mismatch;
+
cf.malloc_context_size = malloc_context_size;
f.poison_heap = poison_heap;
- f.alloc_dealloc_mismatch = alloc_dealloc_mismatch;
- cf.allocator_may_return_null = allocator_may_return_null;
// Check if activation flags need to be overriden.
// FIXME: Add diagnostic to check that activation flags string doesn't
@@ -63,11 +59,13 @@ static struct AsanDeactivatedFlags {
}
void Print() {
- Report("quarantine_size %d, max_redzone %d, poison_heap %d, "
+ Report("quarantine_size_mb %d, max_redzone %d, poison_heap %d, "
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
"allocator_may_return_null %d\n",
- quarantine_size, max_redzone, poison_heap, malloc_context_size,
- alloc_dealloc_mismatch, allocator_may_return_null);
+ allocator_options.quarantine_size_mb, allocator_options.max_redzone,
+ poison_heap, malloc_context_size,
+ allocator_options.alloc_dealloc_mismatch,
+ allocator_options.may_return_null);
}
} asan_deactivated_flags;
@@ -97,16 +95,9 @@ void AsanActivate() {
asan_deactivated_flags.OverrideFromActivationFlags();
- // Restore flag values.
- // FIXME: this is not atomic, and there may be other threads alive.
- flags()->max_redzone = asan_deactivated_flags.max_redzone;
- flags()->alloc_dealloc_mismatch =
- asan_deactivated_flags.alloc_dealloc_mismatch;
-
SetCanPoisonMemory(asan_deactivated_flags.poison_heap);
SetMallocContextSize(asan_deactivated_flags.malloc_context_size);
- ReInitializeAllocator(asan_deactivated_flags.allocator_may_return_null,
- asan_deactivated_flags.quarantine_size);
+ ReInitializeAllocator(asan_deactivated_flags.allocator_options);
asan_is_deactivated = false;
if (common_flags()->verbosity) {
Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=224605&r1=224604&r2=224605&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Fri Dec 19 13:35:11 2014
@@ -205,6 +205,14 @@ QuarantineCache *GetQuarantineCache(Asan
return reinterpret_cast<QuarantineCache *>(ms->quarantine_cache);
}
+void AllocatorOptions::SetFrom(const Flags *f, const CommonFlags *cf) {
+ quarantine_size_mb = f->quarantine_size >> 20;
+ min_redzone = f->redzone;
+ max_redzone = f->max_redzone;
+ may_return_null = cf->allocator_may_return_null;
+ alloc_dealloc_mismatch = f->alloc_dealloc_mismatch;
+}
+
struct Allocator {
static const uptr kMaxAllowedMallocSize =
FIRST_32_SECOND_64(3UL << 30, 64UL << 30);
@@ -217,19 +225,42 @@ struct Allocator {
AllocatorCache fallback_allocator_cache;
QuarantineCache fallback_quarantine_cache;
+ // ------------------- Options --------------------------
+ atomic_uint16_t min_redzone;
+ atomic_uint16_t max_redzone;
+ atomic_uint8_t alloc_dealloc_mismatch;
+
+ // ------------------- Initialization ------------------------
explicit Allocator(LinkerInitialized)
: quarantine(LINKER_INITIALIZED),
fallback_quarantine_cache(LINKER_INITIALIZED) {}
- // ------------------- Initialization ------------------------
- void Initialize(bool may_return_null, uptr quarantine_size) {
- allocator.Init(may_return_null);
- quarantine.Init(quarantine_size, kMaxThreadLocalQuarantine);
- }
-
- void ReInitialize(bool may_return_null, uptr quarantine_size) {
- allocator.SetMayReturnNull(may_return_null);
- quarantine.Init(quarantine_size, kMaxThreadLocalQuarantine);
+ void CheckOptions(const AllocatorOptions &options) const {
+ CHECK_GE(options.min_redzone, 16);
+ CHECK_GE(options.max_redzone, options.min_redzone);
+ CHECK_LE(options.max_redzone, 2048);
+ CHECK(IsPowerOfTwo(options.min_redzone));
+ CHECK(IsPowerOfTwo(options.max_redzone));
+ }
+
+ void SharedInitCode(const AllocatorOptions &options) {
+ CheckOptions(options);
+ quarantine.Init((uptr)options.quarantine_size_mb << 20,
+ kMaxThreadLocalQuarantine);
+ atomic_store(&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch,
+ memory_order_release);
+ atomic_store(&min_redzone, options.min_redzone, memory_order_release);
+ atomic_store(&max_redzone, options.max_redzone, memory_order_release);
+ }
+
+ void Initialize(const AllocatorOptions &options) {
+ allocator.Init(options.may_return_null);
+ SharedInitCode(options);
+ }
+
+ void ReInitialize(const AllocatorOptions &options) {
+ allocator.SetMayReturnNull(options.may_return_null);
+ SharedInitCode(options);
}
// -------------------- Helper methods. -------------------------
@@ -242,8 +273,9 @@ struct Allocator {
user_requested_size <= (1 << 14) - 256 ? 4 :
user_requested_size <= (1 << 15) - 512 ? 5 :
user_requested_size <= (1 << 16) - 1024 ? 6 : 7;
- return Min(Max(rz_log, RZSize2Log(flags()->redzone)),
- RZSize2Log(flags()->max_redzone));
+ u32 min_rz = atomic_load(&min_redzone, memory_order_acquire);
+ u32 max_rz = atomic_load(&max_redzone, memory_order_acquire);
+ return Min(Max(rz_log, RZSize2Log(min_rz)), RZSize2Log(max_rz));
}
// We have an address between two chunks, and we want to report just one.
@@ -419,9 +451,12 @@ struct Allocator {
AllocType alloc_type) {
CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
- if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch)
- ReportAllocTypeMismatch((uptr)ptr, stack,
- (AllocType)m->alloc_type, (AllocType)alloc_type);
+ if (m->alloc_type != alloc_type) {
+ if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) {
+ ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type,
+ (AllocType)alloc_type);
+ }
+ }
CHECK_GE(m->alloc_tid, 0);
if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area.
@@ -619,12 +654,12 @@ StackTrace AsanChunkView::GetFreeStack()
return GetStackTraceFromId(chunk_->free_context_id);
}
-void InitializeAllocator(bool may_return_null, uptr quarantine_size) {
- instance.Initialize(may_return_null, quarantine_size);
+void InitializeAllocator(const AllocatorOptions &options) {
+ instance.Initialize(options);
}
-void ReInitializeAllocator(bool may_return_null, uptr quarantine_size) {
- instance.ReInitialize(may_return_null, quarantine_size);
+void ReInitializeAllocator(const AllocatorOptions &options) {
+ instance.ReInitialize(options);
}
AsanChunkView FindHeapChunkByAddress(uptr addr) {
Modified: compiler-rt/trunk/lib/asan/asan_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.h?rev=224605&r1=224604&r2=224605&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.h (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.h Fri Dec 19 13:35:11 2014
@@ -15,6 +15,7 @@
#ifndef ASAN_ALLOCATOR_H
#define ASAN_ALLOCATOR_H
+#include "asan_flags.h"
#include "asan_internal.h"
#include "asan_interceptors.h"
#include "sanitizer_common/sanitizer_allocator.h"
@@ -31,8 +32,18 @@ enum AllocType {
static const uptr kNumberOfSizeClasses = 255;
struct AsanChunk;
-void InitializeAllocator(bool may_return_null, uptr quarantine_size);
-void ReInitializeAllocator(bool may_return_null, uptr quarantine_size);
+struct AllocatorOptions {
+ u32 quarantine_size_mb;
+ u16 min_redzone;
+ u16 max_redzone;
+ u8 may_return_null;
+ u8 alloc_dealloc_mismatch;
+
+ void SetFrom(const Flags *f, const CommonFlags *cf);
+};
+
+void InitializeAllocator(const AllocatorOptions &options);
+void ReInitializeAllocator(const AllocatorOptions &options);
class AsanChunkView {
public:
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=224605&r1=224604&r2=224605&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Fri Dec 19 13:35:11 2014
@@ -391,8 +391,9 @@ static void AsanInitInternal() {
AsanTSDInit(PlatformTSDDtor);
InstallDeadlySignalHandlers(AsanOnSIGSEGV);
- InitializeAllocator(common_flags()->allocator_may_return_null,
- flags()->quarantine_size);
+ AllocatorOptions allocator_options;
+ allocator_options.SetFrom(flags(), common_flags());
+ InitializeAllocator(allocator_options);
MaybeStartBackgroudThread();
More information about the llvm-commits
mailing list