- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / tcmalloc / chromium / src / tests / debugallocation_test.cc
1 // Copyright (c) 2007, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 // ---
31 // Author: Fred Akalin
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <vector>
36 #include "gperftools/malloc_extension.h"
37 #include "base/logging.h"
38
39 using std::vector;
40
41 vector<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
52 static 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.
66 static int test_to_run = 0;     // set in main() based on argv
67 static 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.
76 DECLARE_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__
82 TEST(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
140 TEST(DebugAllocationTest, DoubleFree) {
141   int* pint = new int;
142   delete pint;
143   IF_DEBUG_EXPECT_DEATH(delete pint, "has been already deallocated");
144 }
145
146 TEST(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
154 TEST(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
162 TEST(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
184 TEST(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
209 TEST(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
220 TEST(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
231 static size_t CurrentlyAllocatedBytes() {
232   size_t value;
233   CHECK(MallocExtension::instance()->GetNumericProperty(
234             "generic.current_allocated_bytes", &value));
235   return value;
236 }
237
238 TEST(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
257 TEST(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
276 TEST(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
298 int 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 }