Chromium Code Reviews| Index: base/allocator/tcmalloc_free_check_test.cc |
| =================================================================== |
| --- base/allocator/tcmalloc_free_check_test.cc (revision 0) |
| +++ base/allocator/tcmalloc_free_check_test.cc (working copy) |
| @@ -0,0 +1,79 @@ |
| +// Copyright 2012 Google Inc. All Rights Reserved. |
|
rvargas (doing something else)
2012/05/19 01:08:04
Use chromium header
kaiwang
2012/05/21 18:11:42
oops.. done
|
| +// Author: kaiwang@google.com (Kai Wang) |
| +#include <stdio.h> |
| +#include "base/allocator/allocator_shim.h" |
|
rvargas (doing something else)
2012/05/19 01:08:04
add a line
kaiwang
2012/05/21 18:11:42
Done.
|
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +// TCMalloc header files |
| +#include "common.h" // For TCMalloc constants like page size, etc. |
| + |
| +using base::allocator::TCMallocDoMallocForTest; |
| +using base::allocator::TCMallocDoFreeForTest; |
| +using base::allocator::ExcludeSpaceForMarkForTest; |
| + |
| +TEST(TCMallocFreeCheck, BadPointerInFirstPageOfTheLargeObject) { |
| + char* p = reinterpret_cast<char*>( |
| + TCMallocDoMallocForTest(ExcludeSpaceForMarkForTest(kMaxSize + 1))); |
| + for (int offset = 1; offset < kPageSize ; offset <<= 1) { |
| + ASSERT_DEATH(TCMallocDoFreeForTest(p + offset), |
| + "Pointer is not pointing to the start of a span"); |
| + } |
| +} |
| + |
| +TEST(TCMallocFreeCheck, BadPageAlignedPointerInsideLargeObject) { |
| + char* p = reinterpret_cast<char*>( |
| + TCMallocDoMallocForTest(ExcludeSpaceForMarkForTest(kMaxSize + 1))); |
| + |
| + for (int offset = kPageSize; offset < kMaxSize; offset += kPageSize) { |
| + // Only the first and last page of a span are in heap map. So for others |
| + // tcmalloc will give a generaal error of invalid pointer. |
|
rvargas (doing something else)
2012/05/19 01:08:04
typo generaal
kaiwang
2012/05/21 18:11:42
Done.
|
| + ASSERT_DEATH(TCMallocDoFreeForTest(p + offset), |
| + "Attempt to free invalid pointer"); |
| + } |
| + ASSERT_DEATH(TCMallocDoFreeForTest(p + kMaxSize), |
| + "Pointer is not inside the first page of a span"); |
| +} |
| + |
| +TEST(TCMallocFreeCheck, DoubleFreeLargeObject) { |
| + char* p = reinterpret_cast<char*>( |
| + TCMallocDoMallocForTest(ExcludeSpaceForMarkForTest(kMaxSize + 1))); |
| + ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), |
| + "Freeing a span not in use"); |
| +} |
| + |
| + |
| +#ifdef NDEBUG |
| +TEST(TCMallocFreeCheck, DoubleFreeSmallObject) { |
| + for (size_t size = 1; |
| + size <= ExcludeSpaceForMarkForTest(kMaxSize); |
| + size <<= 1) { |
| + char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(size)); |
| + ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), |
| + "Circular loop in list detected"); |
| + } |
| +} |
| +#else |
| +TEST(TCMallocFreeCheck, DoubleFreeSmallObject) { |
| + size_t size = 1; |
| + |
| + // When the object is small, tcmalloc validation can not distinguish normal |
| + // memory corruption or double free, because there's not enough space in |
| + // freed objects to keep the mark. |
| + for (; size <= ExcludeSpaceForMarkForTest(kMinClassSize); size <<= 1) { |
| + char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(size)); |
| + ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), |
| + "Memory corrupted"); |
| + } |
| + |
| + for (; size <= ExcludeSpaceForMarkForTest(kMaxSize); size <<= 1) { |
| + char* p = reinterpret_cast<char*>(TCMallocDoMallocForTest(size)); |
| + ASSERT_DEATH(TCMallocDoFreeForTest(p); TCMallocDoFreeForTest(p), |
| + "Attempt to double free"); |
| + } |
| +} |
| +#endif |
| + |
| +int main(int argc, char **argv) { |
| + testing::InitGoogleTest(&argc, argv); |
| + return RUN_ALL_TESTS(); |
| +} |