Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2829)

Unified Diff: base/allocator/allocator_shim_unittest.cc

Issue 2658723007: Hook up allocator shim on mac. (Closed)
Patch Set: remove a debugging test. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/allocator/allocator_shim_override_mac_symbols.h ('k') | base/debug/thread_heap_usage_tracker.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/allocator/allocator_shim_unittest.cc
diff --git a/base/allocator/allocator_shim_unittest.cc b/base/allocator/allocator_shim_unittest.cc
index e45b03dc5392ae44087f41e274b62ad207eca4b0..cff7dd7e86f792b132cea690e7e9c9c976ec2c50 100644
--- a/base/allocator/allocator_shim_unittest.cc
+++ b/base/allocator/allocator_shim_unittest.cc
@@ -4,7 +4,6 @@
#include "base/allocator/allocator_shim.h"
-#include <malloc.h>
#include <stdlib.h>
#include <string.h>
@@ -18,12 +17,20 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_local.h"
+#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_WIN)
#include <windows.h>
+#elif defined(OS_MACOSX)
+#include <malloc/malloc.h>
+#include "third_party/apple_apsl/malloc.h"
#else
+#include <malloc.h>
+#endif
+
+#if !defined(OS_WIN)
#include <unistd.h>
#endif
@@ -83,15 +90,15 @@ class AllocatorShimTest : public testing::Test {
void* address,
size_t size) {
if (instance_) {
- // Address 0x420 is a special sentinel for the NewHandlerConcurrency test.
- // The first time (but only the first one) it is hit it fails, causing the
+ // Size 0xFEED a special sentinel for the NewHandlerConcurrency test.
+ // Hitting it for the first time will cause a failure, causing the
// invocation of the std::new_handler.
- if (address == reinterpret_cast<void*>(0x420)) {
- if (!instance_->did_fail_realloc_0x420_once->Get()) {
- instance_->did_fail_realloc_0x420_once->Set(true);
+ if (size == 0xFEED) {
+ if (!instance_->did_fail_realloc_0xfeed_once->Get()) {
+ instance_->did_fail_realloc_0xfeed_once->Set(true);
return nullptr;
} else {
- return reinterpret_cast<void*>(0x420ul);
+ return address;
}
}
@@ -109,6 +116,44 @@ class AllocatorShimTest : public testing::Test {
self->next->free_function(self->next, address);
}
+ static size_t MockGetSizeEstimate(const AllocatorDispatch* self,
+ void* address) {
+ return self->next->get_size_estimate_function(self->next, address);
+ }
+
+ static unsigned MockBatchMalloc(const AllocatorDispatch* self,
+ size_t size,
+ void** results,
+ unsigned num_requested) {
+ if (instance_) {
+ instance_->batch_mallocs_intercepted_by_size[size] =
+ instance_->batch_mallocs_intercepted_by_size[size] + num_requested;
+ }
+ return self->next->batch_malloc_function(self->next, size, results,
+ num_requested);
+ }
+
+ static void MockBatchFree(const AllocatorDispatch* self,
+ void** to_be_freed,
+ unsigned num_to_be_freed) {
+ if (instance_) {
+ for (unsigned i = 0; i < num_to_be_freed; ++i) {
+ ++instance_->batch_frees_intercepted_by_addr[Hash(to_be_freed[i])];
+ }
+ }
+ self->next->batch_free_function(self->next, to_be_freed, num_to_be_freed);
+ }
+
+ static void MockFreeDefiniteSize(const AllocatorDispatch* self,
+ void* ptr,
+ size_t size) {
+ if (instance_) {
+ ++instance_->frees_intercepted_by_addr[Hash(ptr)];
+ ++instance_->free_definite_sizes_intercepted_by_size[size];
+ }
+ self->next->free_definite_size_function(self->next, ptr, size);
+ }
+
static void NewHandler() {
if (!instance_)
return;
@@ -127,10 +172,20 @@ class AllocatorShimTest : public testing::Test {
memset(&aligned_allocs_intercepted_by_alignment, 0, array_size);
memset(&reallocs_intercepted_by_size, 0, array_size);
memset(&frees_intercepted_by_addr, 0, array_size);
- did_fail_realloc_0x420_once.reset(new ThreadLocalBoolean());
+ memset(&batch_mallocs_intercepted_by_size, 0, array_size);
+ memset(&batch_frees_intercepted_by_addr, 0, array_size);
+ memset(&free_definite_sizes_intercepted_by_size, 0, array_size);
+ did_fail_realloc_0xfeed_once.reset(new ThreadLocalBoolean());
subtle::Release_Store(&num_new_handler_calls, 0);
instance_ = this;
+
+ }
+
+#if defined(OS_MACOSX)
+ static void SetUpTestCase() {
+ InitializeAllocatorShim();
}
+#endif
void TearDown() override { instance_ = nullptr; }
@@ -142,7 +197,10 @@ class AllocatorShimTest : public testing::Test {
size_t reallocs_intercepted_by_size[kMaxSizeTracked];
size_t reallocs_intercepted_by_addr[kMaxSizeTracked];
size_t frees_intercepted_by_addr[kMaxSizeTracked];
- std::unique_ptr<ThreadLocalBoolean> did_fail_realloc_0x420_once;
+ size_t batch_mallocs_intercepted_by_size[kMaxSizeTracked];
+ size_t batch_frees_intercepted_by_addr[kMaxSizeTracked];
+ size_t free_definite_sizes_intercepted_by_size[kMaxSizeTracked];
+ std::unique_ptr<ThreadLocalBoolean> did_fail_realloc_0xfeed_once;
subtle::Atomic32 num_new_handler_calls;
private:
@@ -165,8 +223,9 @@ class ThreadDelegateForNewHandlerTest : public PlatformThread::Delegate {
void ThreadMain() override {
event_->Wait();
- void* res = realloc(reinterpret_cast<void*>(0x420ul), 1);
- EXPECT_EQ(reinterpret_cast<void*>(0x420ul), res);
+ void* temp = malloc(1);
+ void* res = realloc(temp, 0xFEED);
+ EXPECT_EQ(temp, res);
}
private:
@@ -181,7 +240,11 @@ AllocatorDispatch g_mock_dispatch = {
&AllocatorShimTest::MockAllocAligned, /* alloc_aligned_function */
&AllocatorShimTest::MockRealloc, /* realloc_function */
&AllocatorShimTest::MockFree, /* free_function */
- nullptr, /* next */
+ &AllocatorShimTest::MockGetSizeEstimate, /* get_size_estimate_function */
+ &AllocatorShimTest::MockBatchMalloc, /* batch_malloc_function */
+ &AllocatorShimTest::MockBatchFree, /* batch_free_function */
+ &AllocatorShimTest::MockFreeDefiniteSize, /* free_definite_size_function */
+ nullptr, /* next */
};
TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
@@ -196,12 +259,7 @@ TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
ASSERT_GE(zero_allocs_intercepted_by_size[2 * 23], 1u);
#if !defined(OS_WIN)
- void* memalign_ptr = memalign(128, 53);
- ASSERT_NE(nullptr, memalign_ptr);
- ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(memalign_ptr) % 128);
- ASSERT_GE(aligned_allocs_intercepted_by_alignment[128], 1u);
- ASSERT_GE(aligned_allocs_intercepted_by_size[53], 1u);
-
+ const size_t kPageSize = base::GetPageSize();
void* posix_memalign_ptr = nullptr;
int res = posix_memalign(&posix_memalign_ptr, 256, 59);
ASSERT_EQ(0, res);
@@ -212,10 +270,17 @@ TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
void* valloc_ptr = valloc(61);
ASSERT_NE(nullptr, valloc_ptr);
- const size_t kPageSize = base::GetPageSize();
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(valloc_ptr) % kPageSize);
ASSERT_GE(aligned_allocs_intercepted_by_alignment[kPageSize], 1u);
ASSERT_GE(aligned_allocs_intercepted_by_size[61], 1u);
+#endif // !OS_WIN
+
+#if !defined(OS_WIN) && !defined(OS_MACOSX)
+ void* memalign_ptr = memalign(128, 53);
+ ASSERT_NE(nullptr, memalign_ptr);
+ ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(memalign_ptr) % 128);
+ ASSERT_GE(aligned_allocs_intercepted_by_alignment[128], 1u);
+ ASSERT_GE(aligned_allocs_intercepted_by_size[53], 1u);
void* pvalloc_ptr = pvalloc(67);
ASSERT_NE(nullptr, pvalloc_ptr);
@@ -223,12 +288,9 @@ TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
ASSERT_GE(aligned_allocs_intercepted_by_alignment[kPageSize], 1u);
// pvalloc rounds the size up to the next page.
ASSERT_GE(aligned_allocs_intercepted_by_size[kPageSize], 1u);
-#endif // OS_WIN
+#endif // !OS_WIN && !OS_MACOSX
- char* realloc_ptr = static_cast<char*>(realloc(nullptr, 71));
- ASSERT_NE(nullptr, realloc_ptr);
- ASSERT_GE(reallocs_intercepted_by_size[71], 1u);
- ASSERT_GE(reallocs_intercepted_by_addr[Hash(nullptr)], 1u);
+ char* realloc_ptr = static_cast<char*>(malloc(10));
strcpy(realloc_ptr, "foobar");
void* old_realloc_ptr = realloc_ptr;
realloc_ptr = static_cast<char*>(realloc(realloc_ptr, 73));
@@ -242,19 +304,21 @@ TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
free(zero_alloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(zero_alloc_ptr)], 1u);
-#if !defined(OS_WIN)
+#if !defined(OS_WIN) && !defined(OS_MACOSX)
free(memalign_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(memalign_ptr)], 1u);
+ free(pvalloc_ptr);
+ ASSERT_GE(frees_intercepted_by_addr[Hash(pvalloc_ptr)], 1u);
+#endif // !OS_WIN && !OS_MACOSX
+
+#if !defined(OS_WIN)
free(posix_memalign_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(posix_memalign_ptr)], 1u);
free(valloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(valloc_ptr)], 1u);
-
- free(pvalloc_ptr);
- ASSERT_GE(frees_intercepted_by_addr[Hash(pvalloc_ptr)], 1u);
-#endif // OS_WIN
+#endif // !OS_WIN
free(realloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(realloc_ptr)], 1u);
@@ -267,6 +331,41 @@ TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
free(non_hooked_ptr);
}
+#if defined(OS_MACOSX)
+TEST_F(AllocatorShimTest, InterceptLibcSymbolsBatchMallocFree) {
+ InsertAllocatorDispatch(&g_mock_dispatch);
+
+ unsigned count = 13;
+ std::vector<void*> results;
+ results.resize(count);
+ unsigned result_count = malloc_zone_batch_malloc(malloc_default_zone(), 99,
+ results.data(), count);
+ ASSERT_EQ(count, result_count);
+ ASSERT_EQ(count, batch_mallocs_intercepted_by_size[99]);
+
+ std::vector<void*> results_copy(results);
+ malloc_zone_batch_free(malloc_default_zone(), results.data(), count);
+ for (void* result : results_copy) {
+ ASSERT_GE(batch_frees_intercepted_by_addr[Hash(result)], 1u);
+ }
+ RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
+}
+
+TEST_F(AllocatorShimTest, InterceptLibcSymbolsFreeDefiniteSize) {
+ InsertAllocatorDispatch(&g_mock_dispatch);
+
+ void* alloc_ptr = malloc(19);
+ ASSERT_NE(nullptr, alloc_ptr);
+ ASSERT_GE(allocs_intercepted_by_size[19], 1u);
+
+ ChromeMallocZone* default_zone =
+ reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
+ default_zone->free_definite_size(malloc_default_zone(), alloc_ptr, 19);
+ ASSERT_GE(free_definite_sizes_intercepted_by_size[19], 1u);
+ RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
+}
+#endif // defined(OS_MACOSX)
+
TEST_F(AllocatorShimTest, InterceptCppSymbols) {
InsertAllocatorDispatch(&g_mock_dispatch);
@@ -304,8 +403,8 @@ TEST_F(AllocatorShimTest, InterceptCppSymbols) {
// This test exercises the case of concurrent OOM failure, which would end up
// invoking std::new_handler concurrently. This is to cover the CallNewHandler()
// paths of allocator_shim.cc and smoke-test its thread safey.
-// The test creates kNumThreads threads. Each of them does just a
-// realloc(0x420).
+// The test creates kNumThreads threads. Each of them mallocs some memory, and
+// then does a realloc(<new memory>, 0xFEED).
// The shim intercepts such realloc and makes it fail only once on each thread.
// We expect to see excactly kNumThreads invocations of the new_handler.
TEST_F(AllocatorShimTest, NewHandlerConcurrency) {
« no previous file with comments | « base/allocator/allocator_shim_override_mac_symbols.h ('k') | base/debug/thread_heap_usage_tracker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698