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