[compiler-rt] r173776 - [ASan] Do allocate memory even for zero-size allocation requests. Explain why we have to do this in comments.
Alexey Samsonov
samsonov at google.com
Mon Jan 28 23:51:35 PST 2013
Author: samsonov
Date: Tue Jan 29 01:51:34 2013
New Revision: 173776
URL: http://llvm.org/viewvc/llvm-project?rev=173776&view=rev
Log:
[ASan] Do allocate memory even for zero-size allocation requests. Explain why we have to do this in comments.
Modified:
compiler-rt/trunk/lib/asan/asan_allocator2.cc
compiler-rt/trunk/lib/asan/tests/asan_test.cc
Modified: compiler-rt/trunk/lib/asan/asan_allocator2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator2.cc?rev=173776&r1=173775&r2=173776&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator2.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator2.cc Tue Jan 29 01:51:34 2013
@@ -95,8 +95,6 @@ static const uptr kMaxAllowedMallocSize
static const uptr kMaxThreadLocalQuarantine =
FIRST_32_SECOND_64(1 << 18, 1 << 20);
-static const uptr kReturnOnZeroMalloc = 2048; // Zero page is protected.
-
// Every chunk of memory allocated by this allocator can be in one of 3 states:
// CHUNK_AVAILABLE: the chunk is in the free list and ready to be allocated.
// CHUNK_ALLOCATED: the chunk is allocated and not yet freed.
@@ -309,10 +307,12 @@ static void *Allocate(uptr size, uptr al
if (alignment < min_alignment)
alignment = min_alignment;
if (size == 0) {
- if (alignment <= kReturnOnZeroMalloc)
- return reinterpret_cast<void *>(kReturnOnZeroMalloc);
- else
- return 0; // 0 bytes with large alignment requested. Just return 0.
+ // We'd be happy to avoid allocating memory for zero-size requests, but
+ // some programs/tests depend on this behavior and assume that malloc would
+ // not return NULL even for zero-size allocations. Moreover, it looks like
+ // operator new should never return NULL, and results of consecutive "new"
+ // calls must be different even if the allocated size is zero.
+ size = 1;
}
CHECK(IsPowerOfTwo(alignment));
uptr rz_log = ComputeRZLog(size);
@@ -418,7 +418,7 @@ static void *Allocate(uptr size, uptr al
static void Deallocate(void *ptr, StackTrace *stack, AllocType alloc_type) {
uptr p = reinterpret_cast<uptr>(ptr);
- if (p == 0 || p == kReturnOnZeroMalloc) return;
+ if (p == 0) return;
uptr chunk_beg = p - kChunkHeaderSize;
AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
@@ -612,7 +612,7 @@ void *asan_calloc(uptr nmemb, uptr size,
}
void *asan_realloc(void *p, uptr size, StackTrace *stack) {
- if (p == 0 || reinterpret_cast<uptr>(p) == kReturnOnZeroMalloc)
+ if (p == 0)
return Allocate(size, 8, stack, FROM_MALLOC);
if (size == 0) {
Deallocate(p, stack, FROM_MALLOC);
@@ -678,7 +678,7 @@ uptr __asan_get_estimated_allocated_size
bool __asan_get_ownership(const void *p) {
uptr ptr = reinterpret_cast<uptr>(p);
- return (ptr == kReturnOnZeroMalloc) || (AllocationSize(ptr) > 0);
+ return (AllocationSize(ptr) > 0);
}
uptr __asan_get_allocated_size(const void *p) {
@@ -686,7 +686,7 @@ uptr __asan_get_allocated_size(const voi
uptr ptr = reinterpret_cast<uptr>(p);
uptr allocated_size = AllocationSize(ptr);
// Die if p is not malloced or if it is already freed.
- if (allocated_size == 0 && ptr != kReturnOnZeroMalloc) {
+ if (allocated_size == 0) {
GET_STACK_TRACE_FATAL_HERE;
ReportAsanGetAllocatedSizeNotOwned(ptr, &stack);
}
Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=173776&r1=173775&r2=173776&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Tue Jan 29 01:51:34 2013
@@ -391,6 +391,26 @@ TEST(AddressSanitizer, ReallocTest) {
free(ptr2);
}
+TEST(AddressSanitizer, ZeroSizeMallocTest) {
+ // Test that malloc(0) and similar functions don't return NULL.
+ void *ptr = Ident(malloc(0));
+ EXPECT_FALSE(0 == ptr);
+ free(ptr);
+#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
+ int pm_res = posix_memalign(&ptr, 1<<20, 0);
+ EXPECT_EQ(0, pm_res);
+ EXPECT_FALSE(0 == ptr);
+ free(ptr);
+#endif
+ int *int_ptr = new int [0];
+ int *int_ptr2 = new int[0];
+ EXPECT_FALSE(0 == int_ptr);
+ EXPECT_FALSE(0 == int_ptr2);
+ EXPECT_FALSE(int_ptr == int_ptr2);
+ delete[] int_ptr;
+ delete[] int_ptr2;
+}
+
#ifndef __APPLE__
static const char *kMallocUsableSizeErrorMsg =
"AddressSanitizer: attempting to call malloc_usable_size()";
More information about the llvm-commits
mailing list