1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2007, Google Inc. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// All rights reserved. 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// modification, are permitted provided that the following conditions are 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// met: 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// in the documentation and/or other materials provided with the 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// distribution. 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// this software without specific prior written permission. 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// --- 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Author: Fred Akalin 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdio.h> 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdlib.h> 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector> 36#include "gperftools/malloc_extension.h" 37#include "base/logging.h" 38 39using std::vector; 40 41vector<void (*)()> g_testlist; // the tests to run 42 43#define TEST(a, b) \ 44 struct Test_##a##_##b { \ 45 Test_##a##_##b() { g_testlist.push_back(&Run); } \ 46 static void Run(); \ 47 }; \ 48 static Test_##a##_##b g_test_##a##_##b; \ 49 void Test_##a##_##b::Run() 50 51 52static int RUN_ALL_TESTS() { 53 vector<void (*)()>::const_iterator it; 54 for (it = g_testlist.begin(); it != g_testlist.end(); ++it) { 55 (*it)(); // The test will error-exit if there's a problem. 56 } 57 fprintf(stderr, "\nPassed %d tests\n\nPASS\n", 58 static_cast<int>(g_testlist.size())); 59 return 0; 60} 61 62// The death tests are meant to be run from a shell-script driver, which 63// passes in an integer saying which death test to run. We store that 64// test-to-run here, and in the macro use a counter to see when we get 65// to that test, so we can run it. 66static int test_to_run = 0; // set in main() based on argv 67static int test_counter = 0; // incremented every time the macro is called 68#define IF_DEBUG_EXPECT_DEATH(statement, regex) do { \ 69 if (test_counter++ == test_to_run) { \ 70 fprintf(stderr, "Expected regex:%s\n", regex); \ 71 statement; \ 72 } \ 73} while (false) 74 75// This flag won't be compiled in in opt mode. 76DECLARE_int32(max_free_queue_size); 77 78// Test match as well as mismatch rules. But do not test on OS X; on 79// OS X the OS converts new/new[] to malloc before it gets to us, so 80// we are unable to catch these mismatch errors. 81#ifndef __APPLE__ 82TEST(DebugAllocationTest, DeallocMismatch) { 83 // malloc can be matched only by free 84 // new can be matched only by delete and delete(nothrow) 85 // new[] can be matched only by delete[] and delete[](nothrow) 86 // new(nothrow) can be matched only by delete and delete(nothrow) 87 // new(nothrow)[] can be matched only by delete[] and delete[](nothrow) 88 89 // Allocate with malloc. 90 { 91 int* x = static_cast<int*>(malloc(sizeof(*x))); 92 IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete"); 93 IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]"); 94 // Should work fine. 95 free(x); 96 } 97 98 // Allocate with new. 99 { 100 int* x = new int; 101 int* y = new int; 102 IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free"); 103 IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]"); 104 delete x; 105 ::operator delete(y, std::nothrow); 106 } 107 108 // Allocate with new[]. 109 { 110 int* x = new int[1]; 111 int* y = new int[1]; 112 IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free"); 113 IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete"); 114 delete [] x; 115 ::operator delete[](y, std::nothrow); 116 } 117 118 // Allocate with new(nothrow). 119 { 120 int* x = new(std::nothrow) int; 121 int* y = new(std::nothrow) int; 122 IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free"); 123 IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]"); 124 delete x; 125 ::operator delete(y, std::nothrow); 126 } 127 128 // Allocate with new(nothrow)[]. 129 { 130 int* x = new(std::nothrow) int[1]; 131 int* y = new(std::nothrow) int[1]; 132 IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free"); 133 IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete"); 134 delete [] x; 135 ::operator delete[](y, std::nothrow); 136 } 137} 138#endif // #ifdef OS_MACOSX 139 140TEST(DebugAllocationTest, DoubleFree) { 141 int* pint = new int; 142 delete pint; 143 IF_DEBUG_EXPECT_DEATH(delete pint, "has been already deallocated"); 144} 145 146TEST(DebugAllocationTest, StompBefore) { 147 int* pint = new int; 148#ifndef NDEBUG // don't stomp memory if we're not in a position to detect it 149 pint[-1] = 5; 150 IF_DEBUG_EXPECT_DEATH(delete pint, "a word before object"); 151#endif 152} 153 154TEST(DebugAllocationTest, StompAfter) { 155 int* pint = new int; 156#ifndef NDEBUG // don't stomp memory if we're not in a position to detect it 157 pint[1] = 5; 158 IF_DEBUG_EXPECT_DEATH(delete pint, "a word after object"); 159#endif 160} 161 162TEST(DebugAllocationTest, FreeQueueTest) { 163 // Verify that the allocator doesn't return blocks that were recently freed. 164 int* x = new int; 165 int* old_x = x; 166 delete x; 167 x = new int; 168 #if 1 169 // This check should not be read as a universal guarantee of behavior. If 170 // other threads are executing, it would be theoretically possible for this 171 // check to fail despite the efforts of debugallocation.cc to the contrary. 172 // It should always hold under the controlled conditions of this unittest, 173 // however. 174 EXPECT_NE(x, old_x); // Allocator shouldn't return recently freed blocks 175 #else 176 // The below check passes, but since it isn't *required* to pass, I've left 177 // it commented out. 178 // EXPECT_EQ(x, old_x); 179 #endif 180 old_x = NULL; // avoid breaking opt build with an unused variable warning. 181 delete x; 182} 183 184TEST(DebugAllocationTest, DanglingPointerWriteTest) { 185 // This test can only be run if debugging. 186 // 187 // If not debugging, the 'new' following the dangling write might not be 188 // safe. When debugging, we expect the (trashed) deleted block to be on the 189 // list of recently-freed blocks, so the following 'new' will be safe. 190#if 1 191 int* x = new int; 192 delete x; 193 int poisoned_x_value = *x; 194 *x = 1; // a dangling write. 195 196 char* s = new char[FLAGS_max_free_queue_size]; 197 // When we delete s, we push the storage that was previously allocated to x 198 // off the end of the free queue. At that point, the write to that memory 199 // will be detected. 200 IF_DEBUG_EXPECT_DEATH(delete [] s, "Memory was written to after being freed."); 201 202 // restore the poisoned value of x so that we can delete s without causing a 203 // crash. 204 *x = poisoned_x_value; 205 delete [] s; 206#endif 207} 208 209TEST(DebugAllocationTest, DanglingWriteAtExitTest) { 210 int *x = new int; 211 delete x; 212 int old_x_value = *x; 213 *x = 1; 214 // verify that dangling writes are caught at program termination if the 215 // corrupted block never got pushed off of the end of the free queue. 216 IF_DEBUG_EXPECT_DEATH(exit(0), "Memory was written to after being freed."); 217 *x = old_x_value; // restore x so that the test can exit successfully. 218} 219 220TEST(DebugAllocationTest, StackTraceWithDanglingWriteAtExitTest) { 221 int *x = new int; 222 delete x; 223 int old_x_value = *x; 224 *x = 1; 225 // verify that we also get a stack trace when we have a dangling write. 226 // The " @ " is part of the stack trace output. 227 IF_DEBUG_EXPECT_DEATH(exit(0), " @ .*main"); 228 *x = old_x_value; // restore x so that the test can exit successfully. 229} 230 231static size_t CurrentlyAllocatedBytes() { 232 size_t value; 233 CHECK(MallocExtension::instance()->GetNumericProperty( 234 "generic.current_allocated_bytes", &value)); 235 return value; 236} 237 238TEST(DebugAllocationTest, CurrentlyAllocated) { 239 // Clear the free queue 240#if 1 241 FLAGS_max_free_queue_size = 0; 242 // Force a round-trip through the queue management code so that the 243 // new size is seen and the queue of recently-freed blocks is flushed. 244 free(malloc(1)); 245 FLAGS_max_free_queue_size = 1048576; 246#endif 247 248 // Free something and check that it disappears from allocated bytes 249 // immediately. 250 char* p = new char[1000]; 251 size_t after_malloc = CurrentlyAllocatedBytes(); 252 delete[] p; 253 size_t after_free = CurrentlyAllocatedBytes(); 254 EXPECT_LE(after_free, after_malloc - 1000); 255} 256 257TEST(DebugAllocationTest, GetAllocatedSizeTest) { 258#if 1 259 // When debug_allocation is in effect, GetAllocatedSize should return 260 // exactly requested size, since debug_allocation doesn't allow users 261 // to write more than that. 262 for (int i = 0; i < 10; ++i) { 263 void *p = malloc(i); 264 EXPECT_EQ(i, MallocExtension::instance()->GetAllocatedSize(p)); 265 free(p); 266 } 267#endif 268 void* a = malloc(1000); 269 EXPECT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000); 270 // This is just a sanity check. If we allocated too much, alloc is broken 271 EXPECT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000); 272 EXPECT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000); 273 free(a); 274} 275 276TEST(DebugAllocationTest, HugeAlloc) { 277 // This must not be a const variable so it doesn't form an 278 // integral-constant-expression which can be *statically* rejected by the 279 // compiler as too large for the allocation. 280 size_t kTooBig = ~static_cast<size_t>(0); 281 void* a = NULL; 282 283#ifndef NDEBUG 284 285 a = malloc(kTooBig); 286 EXPECT_EQ(NULL, a); 287 288 // kAlsoTooBig is small enough not to get caught by debugallocation's check, 289 // but will still fall through to tcmalloc's check. This must also be 290 // a non-const variable. See kTooBig for more details. 291 size_t kAlsoTooBig = kTooBig - 1024; 292 293 a = malloc(kAlsoTooBig); 294 EXPECT_EQ(NULL, a); 295#endif 296} 297 298int main(int argc, char** argv) { 299 // If you run without args, we run the non-death parts of the test. 300 // Otherwise, argv[1] should be a number saying which death-test 301 // to run. We will output a regexp we expect the death-message 302 // to include, and then run the given death test (which hopefully 303 // will produce that error message). If argv[1] > the number of 304 // death tests, we will run only the non-death parts. One way to 305 // tell when you are done with all tests is when no 'expected 306 // regexp' message is printed for a given argv[1]. 307 if (argc < 2) { 308 test_to_run = -1; // will never match 309 } else { 310 test_to_run = atoi(argv[1]); 311 } 312 return RUN_ALL_TESTS(); 313} 314