summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sanitizer_common/tests')
-rw-r--r--lib/sanitizer_common/tests/CMakeLists.txt1
-rw-r--r--lib/sanitizer_common/tests/sanitizer_allocator_test.cc4
-rw-r--r--lib/sanitizer_common/tests/sanitizer_bitvector_test.cc4
-rw-r--r--lib/sanitizer_common/tests/sanitizer_list_test.cc16
-rw-r--r--lib/sanitizer_common/tests/sanitizer_quarantine_test.cc180
-rw-r--r--lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc12
6 files changed, 209 insertions, 8 deletions
diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt
index 20698b9a8a96a..b310f93743acf 100644
--- a/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/lib/sanitizer_common/tests/CMakeLists.txt
@@ -26,6 +26,7 @@ set(SANITIZER_UNITTESTS
sanitizer_posix_test.cc
sanitizer_printf_test.cc
sanitizer_procmaps_test.cc
+ sanitizer_quarantine_test.cc
sanitizer_stackdepot_test.cc
sanitizer_stacktrace_printer_test.cc
sanitizer_stacktrace_test.cc
diff --git a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
index 8df5efda674ee..e14517fca518f 100644
--- a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <algorithm>
#include <vector>
+#include <random>
#include <set>
using namespace __sanitizer;
@@ -539,6 +540,7 @@ void TestCombinedAllocator() {
Allocator;
Allocator *a = new Allocator;
a->Init(/* may_return_null */ true, kReleaseToOSIntervalNever);
+ std::mt19937 r;
AllocatorCache cache;
memset(&cache, 0, sizeof(cache));
@@ -570,7 +572,7 @@ void TestCombinedAllocator() {
allocated.push_back(x);
}
- random_shuffle(allocated.begin(), allocated.end());
+ std::shuffle(allocated.begin(), allocated.end(), r);
for (uptr i = 0; i < kNumAllocs; i++) {
void *x = allocated[i];
diff --git a/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc b/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc
index 706b4c58968ea..dec5459b25155 100644
--- a/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc
@@ -19,6 +19,7 @@
#include <algorithm>
#include <vector>
+#include <random>
#include <set>
using namespace __sanitizer;
@@ -75,6 +76,7 @@ void Print(const set<uptr> &s) {
template <class BV>
void TestBitVector(uptr expected_size) {
+ std::mt19937 r;
BV bv, bv1, t_bv;
EXPECT_EQ(expected_size, BV::kSize);
bv.clear();
@@ -112,7 +114,7 @@ void TestBitVector(uptr expected_size) {
for (uptr it = 0; it < 30; it++) {
// iota
for (size_t j = 0; j < bits.size(); j++) bits[j] = j;
- random_shuffle(bits.begin(), bits.end());
+ std::shuffle(bits.begin(), bits.end(), r);
set<uptr> s, s1, t_s;
bv.clear();
bv1.clear();
diff --git a/lib/sanitizer_common/tests/sanitizer_list_test.cc b/lib/sanitizer_common/tests/sanitizer_list_test.cc
index fbe53c0375c05..ede9771cb2496 100644
--- a/lib/sanitizer_common/tests/sanitizer_list_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_list_test.cc
@@ -125,6 +125,22 @@ TEST(SanitizerCommon, IntrusiveList) {
CHECK(l.empty());
l.CheckConsistency();
+ l.push_back(x);
+ l.push_back(y);
+ l.push_back(z);
+ l.extract(x, y);
+ CHECK_EQ(l.size(), 2);
+ CHECK_EQ(l.front(), x);
+ CHECK_EQ(l.back(), z);
+ l.CheckConsistency();
+ l.extract(x, z);
+ CHECK_EQ(l.size(), 1);
+ CHECK_EQ(l.front(), x);
+ CHECK_EQ(l.back(), x);
+ l.CheckConsistency();
+ l.pop_front();
+ CHECK(l.empty());
+
List l1, l2;
l1.clear();
l2.clear();
diff --git a/lib/sanitizer_common/tests/sanitizer_quarantine_test.cc b/lib/sanitizer_common/tests/sanitizer_quarantine_test.cc
new file mode 100644
index 0000000000000..23ed5f97ae27f
--- /dev/null
+++ b/lib/sanitizer_common/tests/sanitizer_quarantine_test.cc
@@ -0,0 +1,180 @@
+//===-- sanitizer_quarantine_test.cc --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_quarantine.h"
+#include "gtest/gtest.h"
+
+#include <stdlib.h>
+
+namespace __sanitizer {
+
+struct QuarantineCallback {
+ void Recycle(void *m) {}
+ void *Allocate(uptr size) {
+ return malloc(size);
+ }
+ void Deallocate(void *p) {
+ free(p);
+ }
+};
+
+typedef QuarantineCache<QuarantineCallback> Cache;
+
+static void* kFakePtr = reinterpret_cast<void*>(0xFA83FA83);
+static const size_t kBlockSize = 8;
+
+static QuarantineCallback cb;
+
+static void DeallocateCache(Cache *cache) {
+ while (QuarantineBatch *batch = cache->DequeueBatch())
+ cb.Deallocate(batch);
+}
+
+TEST(SanitizerCommon, QuarantineBatchMerge) {
+ // Verify the trivial case.
+ QuarantineBatch into;
+ into.init(kFakePtr, 4UL);
+ QuarantineBatch from;
+ from.init(kFakePtr, 8UL);
+
+ into.merge(&from);
+
+ ASSERT_EQ(into.count, 2UL);
+ ASSERT_EQ(into.batch[0], kFakePtr);
+ ASSERT_EQ(into.batch[1], kFakePtr);
+ ASSERT_EQ(into.size, 12UL + sizeof(QuarantineBatch));
+ ASSERT_EQ(into.quarantined_size(), 12UL);
+
+ ASSERT_EQ(from.count, 0UL);
+ ASSERT_EQ(from.size, sizeof(QuarantineBatch));
+ ASSERT_EQ(from.quarantined_size(), 0UL);
+
+ // Merge the batch to the limit.
+ for (uptr i = 2; i < QuarantineBatch::kSize; ++i)
+ from.push_back(kFakePtr, 8UL);
+ ASSERT_TRUE(into.count + from.count == QuarantineBatch::kSize);
+ ASSERT_TRUE(into.can_merge(&from));
+
+ into.merge(&from);
+ ASSERT_TRUE(into.count == QuarantineBatch::kSize);
+
+ // No more space, not even for one element.
+ from.init(kFakePtr, 8UL);
+
+ ASSERT_FALSE(into.can_merge(&from));
+}
+
+TEST(SanitizerCommon, QuarantineCacheMergeBatchesEmpty) {
+ Cache cache;
+ Cache to_deallocate;
+ cache.MergeBatches(&to_deallocate);
+
+ ASSERT_EQ(to_deallocate.Size(), 0UL);
+ ASSERT_EQ(to_deallocate.DequeueBatch(), nullptr);
+}
+
+TEST(SanitizerCommon, QuarantineCacheMergeBatchesOneBatch) {
+ Cache cache;
+ cache.Enqueue(cb, kFakePtr, kBlockSize);
+ ASSERT_EQ(kBlockSize + sizeof(QuarantineBatch), cache.Size());
+
+ Cache to_deallocate;
+ cache.MergeBatches(&to_deallocate);
+
+ // Nothing to merge, nothing to deallocate.
+ ASSERT_EQ(kBlockSize + sizeof(QuarantineBatch), cache.Size());
+
+ ASSERT_EQ(to_deallocate.Size(), 0UL);
+ ASSERT_EQ(to_deallocate.DequeueBatch(), nullptr);
+
+ DeallocateCache(&cache);
+}
+
+TEST(SanitizerCommon, QuarantineCacheMergeBatchesSmallBatches) {
+ // Make a cache with two batches small enough to merge.
+ Cache from;
+ from.Enqueue(cb, kFakePtr, kBlockSize);
+ Cache cache;
+ cache.Enqueue(cb, kFakePtr, kBlockSize);
+
+ cache.Transfer(&from);
+ ASSERT_EQ(kBlockSize * 2 + sizeof(QuarantineBatch) * 2, cache.Size());
+
+ Cache to_deallocate;
+ cache.MergeBatches(&to_deallocate);
+
+ // Batches merged, one batch to deallocate.
+ ASSERT_EQ(kBlockSize * 2 + sizeof(QuarantineBatch), cache.Size());
+ ASSERT_EQ(to_deallocate.Size(), sizeof(QuarantineBatch));
+
+ DeallocateCache(&cache);
+ DeallocateCache(&to_deallocate);
+}
+
+TEST(SanitizerCommon, QuarantineCacheMergeBatchesTooBigToMerge) {
+ const uptr kNumBlocks = QuarantineBatch::kSize - 1;
+
+ // Make a cache with two batches small enough to merge.
+ Cache from;
+ Cache cache;
+ for (uptr i = 0; i < kNumBlocks; ++i) {
+ from.Enqueue(cb, kFakePtr, kBlockSize);
+ cache.Enqueue(cb, kFakePtr, kBlockSize);
+ }
+ cache.Transfer(&from);
+ ASSERT_EQ(kBlockSize * kNumBlocks * 2 +
+ sizeof(QuarantineBatch) * 2, cache.Size());
+
+ Cache to_deallocate;
+ cache.MergeBatches(&to_deallocate);
+
+ // Batches cannot be merged.
+ ASSERT_EQ(kBlockSize * kNumBlocks * 2 +
+ sizeof(QuarantineBatch) * 2, cache.Size());
+ ASSERT_EQ(to_deallocate.Size(), 0UL);
+
+ DeallocateCache(&cache);
+}
+
+TEST(SanitizerCommon, QuarantineCacheMergeBatchesALotOfBatches) {
+ const uptr kNumBatchesAfterMerge = 3;
+ const uptr kNumBlocks = QuarantineBatch::kSize * kNumBatchesAfterMerge;
+ const uptr kNumBatchesBeforeMerge = kNumBlocks;
+
+ // Make a cache with many small batches.
+ Cache cache;
+ for (uptr i = 0; i < kNumBlocks; ++i) {
+ Cache from;
+ from.Enqueue(cb, kFakePtr, kBlockSize);
+ cache.Transfer(&from);
+ }
+
+ ASSERT_EQ(kBlockSize * kNumBlocks +
+ sizeof(QuarantineBatch) * kNumBatchesBeforeMerge, cache.Size());
+
+ Cache to_deallocate;
+ cache.MergeBatches(&to_deallocate);
+
+ // All blocks should fit into 3 batches.
+ ASSERT_EQ(kBlockSize * kNumBlocks +
+ sizeof(QuarantineBatch) * kNumBatchesAfterMerge, cache.Size());
+
+ ASSERT_EQ(to_deallocate.Size(),
+ sizeof(QuarantineBatch) *
+ (kNumBatchesBeforeMerge - kNumBatchesAfterMerge));
+
+ DeallocateCache(&cache);
+ DeallocateCache(&to_deallocate);
+}
+
+} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc b/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc
index 1132bfdf62e32..f8b8c12d4ac34 100644
--- a/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc
@@ -67,7 +67,7 @@ static void MarkUidAsPresent(ThreadContextBase *tctx, void *arg) {
static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
// Create and start a main thread.
EXPECT_EQ(0U, registry->CreateThread(get_uid(0), true, -1, 0));
- registry->StartThread(0, 0, 0);
+ registry->StartThread(0, 0, false, 0);
// Create a bunch of threads.
for (u32 i = 1; i <= 10; i++) {
EXPECT_EQ(i, registry->CreateThread(get_uid(i), is_detached(i), 0, 0));
@@ -75,7 +75,7 @@ static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
CheckThreadQuantity(registry, 11, 1, 11);
// Start some of them.
for (u32 i = 1; i <= 5; i++) {
- registry->StartThread(i, 0, 0);
+ registry->StartThread(i, 0, false, 0);
}
CheckThreadQuantity(registry, 11, 6, 11);
// Finish, create and start more threads.
@@ -85,7 +85,7 @@ static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
registry->JoinThread(i, 0);
}
for (u32 i = 6; i <= 10; i++) {
- registry->StartThread(i, 0, 0);
+ registry->StartThread(i, 0, false, 0);
}
std::vector<u32> new_tids;
for (u32 i = 11; i <= 15; i++) {
@@ -112,7 +112,7 @@ static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
}
for (u32 i = 0; i < new_tids.size(); i++) {
u32 tid = new_tids[i];
- registry->StartThread(tid, 0, 0);
+ registry->StartThread(tid, 0, false, 0);
registry->DetachThread(tid, 0);
registry->FinishThread(tid);
}
@@ -189,7 +189,7 @@ void *RunThread(void *arg) {
tids.push_back(
args->registry->CreateThread(0, false, 0, (void*)args->shard));
for (int i = 0; i < kThreadsPerShard; i++)
- args->registry->StartThread(tids[i], 0, (void*)args->shard);
+ args->registry->StartThread(tids[i], 0, false, (void*)args->shard);
for (int i = 0; i < kThreadsPerShard; i++)
args->registry->FinishThread(tids[i]);
for (int i = 0; i < kThreadsPerShard; i++)
@@ -200,7 +200,7 @@ void *RunThread(void *arg) {
static void ThreadedTestRegistry(ThreadRegistry *registry) {
// Create and start a main thread.
EXPECT_EQ(0U, registry->CreateThread(0, true, -1, 0));
- registry->StartThread(0, 0, 0);
+ registry->StartThread(0, 0, false, 0);
pthread_t threads[kNumShards];
RunThreadArgs args[kNumShards];
for (int i = 0; i < kNumShards; i++) {