| 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 <stddef.h> | 9 #include <stddef.h> |
| 10 | 10 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 // Android doesn't implement set_new_handler, so we can't use the | 84 // Android doesn't implement set_new_handler, so we can't use the |
| 85 // OutOfMemoryTest cases. OpenBSD does not support these tests either. | 85 // OutOfMemoryTest cases. OpenBSD does not support these tests either. |
| 86 // Don't test these on ASan/TSan/MSan configurations: only test the real | 86 // Don't test these on ASan/TSan/MSan configurations: only test the real |
| 87 // allocator. | 87 // allocator. |
| 88 // Windows only supports these tests with the allocator shim in place. | 88 // Windows only supports these tests with the allocator shim in place. |
| 89 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \ | 89 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \ |
| 90 !(defined(OS_WIN) && !defined(ALLOCATOR_SHIM)) && \ | 90 !(defined(OS_WIN) && !defined(ALLOCATOR_SHIM)) && \ |
| 91 !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 91 !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| 92 | 92 |
| 93 namespace { | 93 namespace { |
| 94 const char *kOomRegex = "Out of memory"; | 94 #if defined(OS_WIN) |
| 95 // Windows raises an exception rather than using LOG(FATAL) in order to make the |
| 96 // exit code unique to OOM. |
| 97 const char* kOomRegex = ""; |
| 98 const int kExitCode = base::win::kOomExceptionCode; |
| 99 #else |
| 100 const char* kOomRegex = "Out of memory"; |
| 101 const int kExitCode = 1; |
| 102 #endif |
| 95 } // namespace | 103 } // namespace |
| 96 | 104 |
| 97 class OutOfMemoryTest : public testing::Test { | 105 class OutOfMemoryTest : public testing::Test { |
| 98 public: | 106 public: |
| 99 OutOfMemoryTest() | 107 OutOfMemoryTest() |
| 100 : value_(NULL), | 108 : value_(NULL), |
| 101 // Make test size as large as possible minus a few pages so | 109 // Make test size as large as possible minus a few pages so |
| 102 // that alignment or other rounding doesn't make it wrap. | 110 // that alignment or other rounding doesn't make it wrap. |
| 103 test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), | 111 test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), |
| 104 // A test size that is > 2Gb and will cause the allocators to reject | 112 // A test size that is > 2Gb and will cause the allocators to reject |
| (...skipping 15 matching lines...) Expand all Loading... |
| 120 // Must call EnableTerminationOnOutOfMemory() because that is called from | 128 // Must call EnableTerminationOnOutOfMemory() because that is called from |
| 121 // chrome's main function and therefore hasn't been called yet. | 129 // chrome's main function and therefore hasn't been called yet. |
| 122 // Since this call may result in another thread being created and death | 130 // Since this call may result in another thread being created and death |
| 123 // tests shouldn't be started in a multithread environment, this call | 131 // tests shouldn't be started in a multithread environment, this call |
| 124 // should be done inside of the ASSERT_DEATH. | 132 // should be done inside of the ASSERT_DEATH. |
| 125 base::EnableTerminationOnOutOfMemory(); | 133 base::EnableTerminationOnOutOfMemory(); |
| 126 } | 134 } |
| 127 }; | 135 }; |
| 128 | 136 |
| 129 TEST_F(OutOfMemoryDeathTest, New) { | 137 TEST_F(OutOfMemoryDeathTest, New) { |
| 130 ASSERT_DEATH({ | 138 ASSERT_EXIT({ |
| 131 SetUpInDeathAssert(); | 139 SetUpInDeathAssert(); |
| 132 value_ = operator new(test_size_); | 140 value_ = operator new(test_size_); |
| 133 }, kOomRegex); | 141 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 134 } | 142 } |
| 135 | 143 |
| 136 TEST_F(OutOfMemoryDeathTest, NewArray) { | 144 TEST_F(OutOfMemoryDeathTest, NewArray) { |
| 137 ASSERT_DEATH({ | 145 ASSERT_EXIT({ |
| 138 SetUpInDeathAssert(); | 146 SetUpInDeathAssert(); |
| 139 value_ = new char[test_size_]; | 147 value_ = new char[test_size_]; |
| 140 }, kOomRegex); | 148 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 141 } | 149 } |
| 142 | 150 |
| 143 TEST_F(OutOfMemoryDeathTest, Malloc) { | 151 TEST_F(OutOfMemoryDeathTest, Malloc) { |
| 144 ASSERT_DEATH({ | 152 ASSERT_EXIT({ |
| 145 SetUpInDeathAssert(); | 153 SetUpInDeathAssert(); |
| 146 value_ = malloc(test_size_); | 154 value_ = malloc(test_size_); |
| 147 }, kOomRegex); | 155 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 148 } | 156 } |
| 149 | 157 |
| 150 TEST_F(OutOfMemoryDeathTest, Realloc) { | 158 TEST_F(OutOfMemoryDeathTest, Realloc) { |
| 151 ASSERT_DEATH({ | 159 ASSERT_EXIT({ |
| 152 SetUpInDeathAssert(); | 160 SetUpInDeathAssert(); |
| 153 value_ = realloc(NULL, test_size_); | 161 value_ = realloc(NULL, test_size_); |
| 154 }, kOomRegex); | 162 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 155 } | 163 } |
| 156 | 164 |
| 157 TEST_F(OutOfMemoryDeathTest, Calloc) { | 165 TEST_F(OutOfMemoryDeathTest, Calloc) { |
| 158 ASSERT_DEATH({ | 166 ASSERT_EXIT({ |
| 159 SetUpInDeathAssert(); | 167 SetUpInDeathAssert(); |
| 160 value_ = calloc(1024, test_size_ / 1024L); | 168 value_ = calloc(1024, test_size_ / 1024L); |
| 161 }, kOomRegex); | 169 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 162 } | 170 } |
| 163 | 171 |
| 164 TEST_F(OutOfMemoryDeathTest, AlignedAlloc) { | 172 TEST_F(OutOfMemoryDeathTest, AlignedAlloc) { |
| 165 ASSERT_DEATH({ | 173 ASSERT_EXIT({ |
| 166 SetUpInDeathAssert(); | 174 SetUpInDeathAssert(); |
| 167 value_ = base::AlignedAlloc(test_size_, 8); | 175 value_ = base::AlignedAlloc(test_size_, 8); |
| 168 }, kOomRegex); | 176 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 169 } | 177 } |
| 170 | 178 |
| 171 // POSIX does not define an aligned realloc function. | 179 // POSIX does not define an aligned realloc function. |
| 172 #if defined(OS_WIN) | 180 #if defined(OS_WIN) |
| 173 TEST_F(OutOfMemoryDeathTest, AlignedRealloc) { | 181 TEST_F(OutOfMemoryDeathTest, AlignedRealloc) { |
| 174 ASSERT_DEATH({ | 182 ASSERT_EXIT({ |
| 175 SetUpInDeathAssert(); | 183 SetUpInDeathAssert(); |
| 176 value_ = _aligned_realloc(NULL, test_size_, 8); | 184 value_ = _aligned_realloc(NULL, test_size_, 8); |
| 177 }, kOomRegex); | 185 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 178 } | 186 } |
| 179 #endif // defined(OS_WIN) | 187 #endif // defined(OS_WIN) |
| 180 | 188 |
| 181 // OS X has no 2Gb allocation limit. | 189 // OS X has no 2Gb allocation limit. |
| 182 // See https://crbug.com/169327. | 190 // See https://crbug.com/169327. |
| 183 #if !defined(OS_MACOSX) | 191 #if !defined(OS_MACOSX) |
| 184 TEST_F(OutOfMemoryDeathTest, SecurityNew) { | 192 TEST_F(OutOfMemoryDeathTest, SecurityNew) { |
| 185 ASSERT_DEATH({ | 193 ASSERT_EXIT({ |
| 186 SetUpInDeathAssert(); | 194 SetUpInDeathAssert(); |
| 187 value_ = operator new(insecure_test_size_); | 195 value_ = operator new(insecure_test_size_); |
| 188 }, kOomRegex); | 196 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 189 } | 197 } |
| 190 | 198 |
| 191 TEST_F(OutOfMemoryDeathTest, SecurityNewArray) { | 199 TEST_F(OutOfMemoryDeathTest, SecurityNewArray) { |
| 192 ASSERT_DEATH({ | 200 ASSERT_EXIT({ |
| 193 SetUpInDeathAssert(); | 201 SetUpInDeathAssert(); |
| 194 value_ = new char[insecure_test_size_]; | 202 value_ = new char[insecure_test_size_]; |
| 195 }, kOomRegex); | 203 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 196 } | 204 } |
| 197 | 205 |
| 198 TEST_F(OutOfMemoryDeathTest, SecurityMalloc) { | 206 TEST_F(OutOfMemoryDeathTest, SecurityMalloc) { |
| 199 ASSERT_DEATH({ | 207 ASSERT_EXIT({ |
| 200 SetUpInDeathAssert(); | 208 SetUpInDeathAssert(); |
| 201 value_ = malloc(insecure_test_size_); | 209 value_ = malloc(insecure_test_size_); |
| 202 }, kOomRegex); | 210 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 203 } | 211 } |
| 204 | 212 |
| 205 TEST_F(OutOfMemoryDeathTest, SecurityRealloc) { | 213 TEST_F(OutOfMemoryDeathTest, SecurityRealloc) { |
| 206 ASSERT_DEATH({ | 214 ASSERT_EXIT({ |
| 207 SetUpInDeathAssert(); | 215 SetUpInDeathAssert(); |
| 208 value_ = realloc(NULL, insecure_test_size_); | 216 value_ = realloc(NULL, insecure_test_size_); |
| 209 }, kOomRegex); | 217 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 210 } | 218 } |
| 211 | 219 |
| 212 TEST_F(OutOfMemoryDeathTest, SecurityCalloc) { | 220 TEST_F(OutOfMemoryDeathTest, SecurityCalloc) { |
| 213 ASSERT_DEATH({ | 221 ASSERT_EXIT({ |
| 214 SetUpInDeathAssert(); | 222 SetUpInDeathAssert(); |
| 215 value_ = calloc(1024, insecure_test_size_ / 1024L); | 223 value_ = calloc(1024, insecure_test_size_ / 1024L); |
| 216 }, kOomRegex); | 224 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 217 } | 225 } |
| 218 | 226 |
| 219 TEST_F(OutOfMemoryDeathTest, SecurityAlignedAlloc) { | 227 TEST_F(OutOfMemoryDeathTest, SecurityAlignedAlloc) { |
| 220 ASSERT_DEATH({ | 228 ASSERT_EXIT({ |
| 221 SetUpInDeathAssert(); | 229 SetUpInDeathAssert(); |
| 222 value_ = base::AlignedAlloc(insecure_test_size_, 8); | 230 value_ = base::AlignedAlloc(insecure_test_size_, 8); |
| 223 }, kOomRegex); | 231 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 224 } | 232 } |
| 225 | 233 |
| 226 // POSIX does not define an aligned realloc function. | 234 // POSIX does not define an aligned realloc function. |
| 227 #if defined(OS_WIN) | 235 #if defined(OS_WIN) |
| 228 TEST_F(OutOfMemoryDeathTest, SecurityAlignedRealloc) { | 236 TEST_F(OutOfMemoryDeathTest, SecurityAlignedRealloc) { |
| 229 ASSERT_DEATH({ | 237 ASSERT_EXIT({ |
| 230 SetUpInDeathAssert(); | 238 SetUpInDeathAssert(); |
| 231 value_ = _aligned_realloc(NULL, insecure_test_size_, 8); | 239 value_ = _aligned_realloc(NULL, insecure_test_size_, 8); |
| 232 }, kOomRegex); | 240 }, testing::ExitedWithCode(kExitCode), kOomRegex); |
| 233 } | 241 } |
| 234 #endif // defined(OS_WIN) | 242 #endif // defined(OS_WIN) |
| 235 #endif // !defined(OS_MACOSX) | 243 #endif // !defined(OS_MACOSX) |
| 236 | 244 |
| 237 #if defined(OS_LINUX) | 245 #if defined(OS_LINUX) |
| 238 | 246 |
| 239 TEST_F(OutOfMemoryDeathTest, Valloc) { | 247 TEST_F(OutOfMemoryDeathTest, Valloc) { |
| 240 ASSERT_DEATH({ | 248 ASSERT_DEATH({ |
| 241 SetUpInDeathAssert(); | 249 SetUpInDeathAssert(); |
| 242 value_ = valloc(test_size_); | 250 value_ = valloc(test_size_); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i) | 439 for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i) |
| 432 EXPECT_EQ(0, bytes[i]); | 440 EXPECT_EQ(0, bytes[i]); |
| 433 free(value_); | 441 free(value_); |
| 434 | 442 |
| 435 EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &value_)); | 443 EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &value_)); |
| 436 EXPECT_TRUE(value_ == NULL); | 444 EXPECT_TRUE(value_ == NULL); |
| 437 } | 445 } |
| 438 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 446 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| 439 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && !(defined(OS_WIN) && | 447 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && !(defined(OS_WIN) && |
| 440 // !defined(ALLOCATOR_SHIM)) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 448 // !defined(ALLOCATOR_SHIM)) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| OLD | NEW |