diff options
Diffstat (limited to 'chromium/base/process/memory_unittest.cc')
-rw-r--r-- | chromium/base/process/memory_unittest.cc | 96 |
1 files changed, 73 insertions, 23 deletions
diff --git a/chromium/base/process/memory_unittest.cc b/chromium/base/process/memory_unittest.cc index e5c759d5711..048c09d38c1 100644 --- a/chromium/base/process/memory_unittest.cc +++ b/chromium/base/process/memory_unittest.cc @@ -121,9 +121,7 @@ TEST(ProcessMemoryTest, MacMallocFailureDoesNotTerminate) { buf = malloc(std::numeric_limits<size_t>::max() - (2 * PAGE_SIZE) - 1); }, testing::KilledBySignal(SIGTRAP), - "\\*\\*\\* error: can't allocate region.*" - "(Terminating process due to a potential for future heap " - "corruption){0}"); + "\\*\\*\\* error: can't allocate region.*\\n?.*"); base::debug::Alias(buf); } @@ -143,8 +141,8 @@ TEST(ProcessMemoryTest, MacTerminateOnHeapCorruption) { ASSERT_DEATH(free(buf), "attempting free on address which " "was not malloc\\(\\)-ed"); #else - ASSERT_DEATH(free(buf), "being freed.*" - "\\*\\*\\* set a breakpoint in malloc_error_break to debug.*" + ASSERT_DEATH(free(buf), "being freed.*\\n?\\.*" + "\\*\\*\\* set a breakpoint in malloc_error_break to debug.*\\n?.*" "Terminating process due to a potential for future heap corruption"); #endif // ARCH_CPU_64_BITS || defined(ADDRESS_SANITIZER) } @@ -154,13 +152,9 @@ TEST(ProcessMemoryTest, MacTerminateOnHeapCorruption) { // Android doesn't implement set_new_handler, so we can't use the // OutOfMemoryTest cases. // OpenBSD does not support these tests either. -// AddressSanitizer and ThreadSanitizer define the malloc()/free()/etc. -// functions so that they don't crash if the program is out of memory, so the -// OOM tests aren't supposed to work. // TODO(vandebo) make this work on Windows too. #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \ - !defined(OS_WIN) && \ - !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) + !defined(OS_WIN) #if defined(USE_TCMALLOC) extern "C" { @@ -168,14 +162,14 @@ int tc_set_new_mode(int mode); } #endif // defined(USE_TCMALLOC) -class OutOfMemoryDeathTest : public testing::Test { +class OutOfMemoryTest : public testing::Test { public: - OutOfMemoryDeathTest() - : value_(NULL), - // Make test size as large as possible minus a few pages so - // that alignment or other rounding doesn't make it wrap. - test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), - signed_test_size_(std::numeric_limits<ssize_t>::max()) { + OutOfMemoryTest() + : value_(NULL), + // Make test size as large as possible minus a few pages so + // that alignment or other rounding doesn't make it wrap. + test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), + signed_test_size_(std::numeric_limits<ssize_t>::max()) { } #if defined(USE_TCMALLOC) @@ -188,6 +182,14 @@ class OutOfMemoryDeathTest : public testing::Test { } #endif // defined(USE_TCMALLOC) + protected: + void* value_; + size_t test_size_; + ssize_t signed_test_size_; +}; + +class OutOfMemoryDeathTest : public OutOfMemoryTest { + public: void SetUpInDeathAssert() { // Must call EnableTerminationOnOutOfMemory() because that is called from // chrome's main function and therefore hasn't been called yet. @@ -196,10 +198,6 @@ class OutOfMemoryDeathTest : public testing::Test { // should be done inside of the ASSERT_DEATH. base::EnableTerminationOnOutOfMemory(); } - - void* value_; - size_t test_size_; - ssize_t signed_test_size_; }; TEST_F(OutOfMemoryDeathTest, New) { @@ -245,12 +243,15 @@ TEST_F(OutOfMemoryDeathTest, Valloc) { } #if defined(OS_LINUX) + +#if PVALLOC_AVAILABLE == 1 TEST_F(OutOfMemoryDeathTest, Pvalloc) { ASSERT_DEATH({ SetUpInDeathAssert(); value_ = pvalloc(test_size_); }, ""); } +#endif // PVALLOC_AVAILABLE == 1 TEST_F(OutOfMemoryDeathTest, Memalign) { ASSERT_DEATH({ @@ -374,5 +375,54 @@ TEST_F(OutOfMemoryDeathTest, PsychoticallyBigObjCObject) { #endif // !ARCH_CPU_64_BITS #endif // OS_MACOSX -#endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && - // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) +class OutOfMemoryHandledTest : public OutOfMemoryTest { + public: + static const size_t kSafeMallocSize = 512; + static const size_t kSafeCallocSize = 128; + static const size_t kSafeCallocItems = 4; + + virtual void SetUp() { + OutOfMemoryTest::SetUp(); + + // We enable termination on OOM - just as Chrome does at early + // initialization - and test that UncheckedMalloc and UncheckedCalloc + // properly by-pass this in order to allow the caller to handle OOM. + base::EnableTerminationOnOutOfMemory(); + } +}; + +// TODO(b.kelemen): make UncheckedMalloc and UncheckedCalloc work +// on Windows as well. +// UncheckedMalloc() and UncheckedCalloc() work as regular malloc()/calloc() +// under sanitizer tools. +#if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) +TEST_F(OutOfMemoryHandledTest, UncheckedMalloc) { + EXPECT_TRUE(base::UncheckedMalloc(kSafeMallocSize, &value_)); + EXPECT_TRUE(value_ != NULL); + free(value_); + + EXPECT_FALSE(base::UncheckedMalloc(test_size_, &value_)); + EXPECT_TRUE(value_ == NULL); +} + +TEST_F(OutOfMemoryHandledTest, UncheckedCalloc) { + EXPECT_TRUE(base::UncheckedCalloc(1, kSafeMallocSize, &value_)); + EXPECT_TRUE(value_ != NULL); + const char* bytes = static_cast<const char*>(value_); + for (size_t i = 0; i < kSafeMallocSize; ++i) + EXPECT_EQ(0, bytes[i]); + free(value_); + + EXPECT_TRUE( + base::UncheckedCalloc(kSafeCallocItems, kSafeCallocSize, &value_)); + EXPECT_TRUE(value_ != NULL); + bytes = static_cast<const char*>(value_); + for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i) + EXPECT_EQ(0, bytes[i]); + free(value_); + + EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &value_)); + EXPECT_TRUE(value_ == NULL); +} +#endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) +#endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && !defined(OS_WIN) |