OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #define _CRT_SECURE_NO_WARNINGS | 5 #define _CRT_SECURE_NO_WARNINGS |
6 | 6 |
7 #include "base/process/memory.h" | 7 #include "base/process/memory.h" |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \ | 159 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \ |
160 !defined(OS_WIN) && \ | 160 !defined(OS_WIN) && \ |
161 !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) | 161 !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) |
162 | 162 |
163 #if defined(USE_TCMALLOC) | 163 #if defined(USE_TCMALLOC) |
164 extern "C" { | 164 extern "C" { |
165 int tc_set_new_mode(int mode); | 165 int tc_set_new_mode(int mode); |
166 } | 166 } |
167 #endif // defined(USE_TCMALLOC) | 167 #endif // defined(USE_TCMALLOC) |
168 | 168 |
169 class OutOfMemoryDeathTest : public testing::Test { | 169 class OutOfMemoryTest : public testing::Test { |
170 public: | 170 public: |
171 OutOfMemoryDeathTest() | 171 OutOfMemoryTest() |
172 : value_(NULL), | 172 : value_(NULL), |
173 // Make test size as large as possible minus a few pages so | 173 // Make test size as large as possible minus a few pages so |
174 // that alignment or other rounding doesn't make it wrap. | 174 // that alignment or other rounding doesn't make it wrap. |
175 test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), | 175 test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), |
176 signed_test_size_(std::numeric_limits<ssize_t>::max()) { | 176 signed_test_size_(std::numeric_limits<ssize_t>::max()) { |
177 } | 177 } |
178 | 178 |
179 #if defined(USE_TCMALLOC) | 179 #if defined(USE_TCMALLOC) |
180 virtual void SetUp() OVERRIDE { | 180 virtual void SetUp() OVERRIDE { |
181 tc_set_new_mode(1); | 181 tc_set_new_mode(1); |
182 } | 182 } |
183 | 183 |
184 virtual void TearDown() OVERRIDE { | 184 virtual void TearDown() OVERRIDE { |
185 tc_set_new_mode(0); | 185 tc_set_new_mode(0); |
186 } | 186 } |
187 #endif // defined(USE_TCMALLOC) | 187 #endif // defined(USE_TCMALLOC) |
188 | 188 |
| 189 protected: |
| 190 void* value_; |
| 191 size_t test_size_; |
| 192 ssize_t signed_test_size_; |
| 193 }; |
| 194 |
| 195 class OutOfMemoryDeathTest : public OutOfMemoryTest { |
| 196 public: |
189 void SetUpInDeathAssert() { | 197 void SetUpInDeathAssert() { |
190 // Must call EnableTerminationOnOutOfMemory() because that is called from | 198 // Must call EnableTerminationOnOutOfMemory() because that is called from |
191 // chrome's main function and therefore hasn't been called yet. | 199 // chrome's main function and therefore hasn't been called yet. |
192 // Since this call may result in another thread being created and death | 200 // Since this call may result in another thread being created and death |
193 // tests shouldn't be started in a multithread environment, this call | 201 // tests shouldn't be started in a multithread environment, this call |
194 // should be done inside of the ASSERT_DEATH. | 202 // should be done inside of the ASSERT_DEATH. |
195 base::EnableTerminationOnOutOfMemory(); | 203 base::EnableTerminationOnOutOfMemory(); |
196 } | 204 } |
197 | |
198 void* value_; | |
199 size_t test_size_; | |
200 ssize_t signed_test_size_; | |
201 }; | 205 }; |
202 | 206 |
203 TEST_F(OutOfMemoryDeathTest, New) { | 207 TEST_F(OutOfMemoryDeathTest, New) { |
204 ASSERT_DEATH({ | 208 ASSERT_DEATH({ |
205 SetUpInDeathAssert(); | 209 SetUpInDeathAssert(); |
206 value_ = operator new(test_size_); | 210 value_ = operator new(test_size_); |
207 }, ""); | 211 }, ""); |
208 } | 212 } |
209 | 213 |
210 TEST_F(OutOfMemoryDeathTest, NewArray) { | 214 TEST_F(OutOfMemoryDeathTest, NewArray) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 TEST_F(OutOfMemoryDeathTest, PsychoticallyBigObjCObject) { | 372 TEST_F(OutOfMemoryDeathTest, PsychoticallyBigObjCObject) { |
369 ASSERT_DEATH({ | 373 ASSERT_DEATH({ |
370 SetUpInDeathAssert(); | 374 SetUpInDeathAssert(); |
371 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} | 375 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} |
372 }, ""); | 376 }, ""); |
373 } | 377 } |
374 | 378 |
375 #endif // !ARCH_CPU_64_BITS | 379 #endif // !ARCH_CPU_64_BITS |
376 #endif // OS_MACOSX | 380 #endif // OS_MACOSX |
377 | 381 |
| 382 class OutOfMemoryHandledTest : public OutOfMemoryTest { |
| 383 public: |
| 384 static const size_t kSafeMallocSize = 512; |
| 385 static const size_t kSafeCallocSize = 128; |
| 386 static const size_t kSafeCallocItems = 4; |
| 387 |
| 388 virtual void SetUp() { |
| 389 OutOfMemoryTest::SetUp(); |
| 390 |
| 391 // We enable termination on OOM - just as Chrome does at early |
| 392 // initialization - and test that UncheckedMalloc and UncheckedCalloc |
| 393 // properly by-pass this in order to allow the caller to handle OOM. |
| 394 base::EnableTerminationOnOutOfMemory(); |
| 395 } |
| 396 }; |
| 397 |
| 398 // TODO(b.kelemen): make UncheckedMalloc and UncheckedCalloc work |
| 399 // on Windows as well. |
| 400 |
| 401 TEST_F(OutOfMemoryHandledTest, UncheckedMalloc) { |
| 402 EXPECT_TRUE(base::UncheckedMalloc(kSafeMallocSize, &value_)); |
| 403 EXPECT_TRUE(value_ != NULL); |
| 404 free(value_); |
| 405 |
| 406 EXPECT_FALSE(base::UncheckedMalloc(test_size_, &value_)); |
| 407 EXPECT_TRUE(value_ == NULL); |
| 408 } |
| 409 |
| 410 TEST_F(OutOfMemoryHandledTest, UncheckedCalloc) { |
| 411 EXPECT_TRUE(base::UncheckedCalloc(1, kSafeMallocSize, &value_)); |
| 412 EXPECT_TRUE(value_ != NULL); |
| 413 const char* bytes = static_cast<const char*>(value_); |
| 414 for (size_t i = 0; i < kSafeMallocSize; ++i) |
| 415 EXPECT_EQ(0, bytes[i]); |
| 416 free(value_); |
| 417 |
| 418 EXPECT_TRUE( |
| 419 base::UncheckedCalloc(kSafeCallocItems, kSafeCallocSize, &value_)); |
| 420 EXPECT_TRUE(value_ != NULL); |
| 421 bytes = static_cast<const char*>(value_); |
| 422 for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i) |
| 423 EXPECT_EQ(0, bytes[i]); |
| 424 free(value_); |
| 425 |
| 426 EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &value_)); |
| 427 EXPECT_TRUE(value_ == NULL); |
| 428 } |
| 429 |
378 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && | 430 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && |
379 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) | 431 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) |
OLD | NEW |