| 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 |