summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_allocator.h
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-03-06 14:54:08 +0000
committerReid Kleckner <reid@kleckner.net>2013-03-06 14:54:08 +0000
commit5d3dcb8fa4947ebeab61bcf512ab352576d0fb41 (patch)
tree6280a5097d4b0c90aeb14aa48aa58c119a2f3877 /lib/sanitizer_common/sanitizer_allocator.h
parentbcf393e373713021c88b0e39c73a615a4e0f3fd2 (diff)
downloadcompiler-rt-5d3dcb8fa4947ebeab61bcf512ab352576d0fb41.tar.gz
compiler-rt-5d3dcb8fa4947ebeab61bcf512ab352576d0fb41.tar.bz2
compiler-rt-5d3dcb8fa4947ebeab61bcf512ab352576d0fb41.tar.xz
[sanitizers] Fix check failure on dealloc from new thread
Summary: Adds a test for this case, which was reduced from a chromium build of WebKit's DumpRenderTree. Reviewers: eugenis CC: glider Differential Revision: http://llvm-reviews.chandlerc.com/D495 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@176552 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_allocator.h')
-rw-r--r--lib/sanitizer_common/sanitizer_allocator.h15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/sanitizer_common/sanitizer_allocator.h b/lib/sanitizer_common/sanitizer_allocator.h
index 48b299aa..e1f06f3b 100644
--- a/lib/sanitizer_common/sanitizer_allocator.h
+++ b/lib/sanitizer_common/sanitizer_allocator.h
@@ -342,6 +342,7 @@ class SizeClassAllocator64 {
NOINLINE void DeallocateBatch(AllocatorStats *stat, uptr class_id, Batch *b) {
RegionInfo *region = GetRegionInfo(class_id);
+ CHECK_GT(b->count, 0);
region->free_list.Push(b);
region->n_freed += b->count;
}
@@ -535,6 +536,7 @@ class SizeClassAllocator64 {
beg_idx += count * size;
if (beg_idx + count * size + size > region->mapped_user)
break;
+ CHECK_GT(b->count, 0);
region->free_list.Push(b);
}
return b;
@@ -620,6 +622,7 @@ class SizeClassAllocator32 {
CHECK_LT(class_id, kNumClasses);
SizeClassInfo *sci = GetSizeClassInfo(class_id);
SpinMutexLock l(&sci->mutex);
+ CHECK_GT(b->count, 0);
sci->free_list.push_front(b);
}
@@ -741,12 +744,15 @@ class SizeClassAllocator32 {
}
b->batch[b->count++] = (void*)i;
if (b->count == max_count) {
+ CHECK_GT(b->count, 0);
sci->free_list.push_back(b);
b = 0;
}
}
- if (b)
+ if (b) {
+ CHECK_GT(b->count, 0);
sci->free_list.push_back(b);
+ }
}
struct State {
@@ -791,8 +797,12 @@ struct SizeClassAllocatorLocalCache {
void Deallocate(SizeClassAllocator *allocator, uptr class_id, void *p) {
CHECK_NE(class_id, 0UL);
CHECK_LT(class_id, kNumClasses);
+ // If the first allocator call on a new thread is a deallocation, then
+ // max_count will be zero, leading to check failure.
+ InitCache();
stats_.Add(AllocatorStatFreed, SizeClassMap::Size(class_id));
PerClass *c = &per_class_[class_id];
+ CHECK_NE(c->max_count, 0UL);
if (UNLIKELY(c->count == c->max_count))
Drain(allocator, class_id);
c->batch[c->count++] = p;
@@ -818,7 +828,7 @@ struct SizeClassAllocatorLocalCache {
AllocatorStats stats_;
void InitCache() {
- if (per_class_[0].max_count)
+ if (per_class_[1].max_count)
return;
for (uptr i = 0; i < kNumClasses; i++) {
PerClass *c = &per_class_[i];
@@ -853,6 +863,7 @@ struct SizeClassAllocatorLocalCache {
}
b->count = cnt;
c->count -= cnt;
+ CHECK_GT(b->count, 0);
allocator->DeallocateBatch(&stats_, class_id, b);
}
};