123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #define _CRT_SECURE_NO_WARNINGS
- #include "base/process/memory.h"
- #include <stddef.h>
- #include <limits>
- #include <tuple>
- #include <vector>
- #include "base/allocator/allocator_check.h"
- #include "base/allocator/buildflags.h"
- #include "base/allocator/partition_allocator/page_allocator.h"
- #include "base/compiler_specific.h"
- #include "base/debug/alias.h"
- #include "base/memory/aligned_memory.h"
- #include "base/memory/page_size.h"
- #include "build/build_config.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #if BUILDFLAG(IS_WIN)
- #include <windows.h>
- #endif
- #if BUILDFLAG(IS_POSIX)
- #include <errno.h>
- #endif
- #if BUILDFLAG(IS_MAC)
- #include <malloc/malloc.h>
- #include "base/allocator/allocator_interception_mac.h"
- #include "base/allocator/allocator_shim.h"
- #include "base/allocator/buildflags.h"
- #include "base/process/memory_unittest_mac.h"
- #endif
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- #include <malloc.h>
- #include "base/test/malloc_wrapper.h"
- #endif
- #if BUILDFLAG(IS_ANDROID)
- #include "base/android/build_info.h"
- #endif
- #if BUILDFLAG(IS_WIN)
- #if defined(COMPILER_MSVC)
- // ssize_t needed for OutOfMemoryTest.
- #if defined(_WIN64)
- typedef __int64 ssize_t;
- #else
- typedef long ssize_t;
- #endif
- #endif
- // HeapQueryInformation function pointer.
- typedef BOOL (WINAPI* HeapQueryFn) \
- (HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
- #endif // BUILDFLAG(IS_WIN)
- #if BUILDFLAG(IS_MAC)
- // For the following Mac tests:
- // Note that base::EnableTerminationOnHeapCorruption() is called as part of
- // test suite setup and does not need to be done again, else mach_override
- // will fail.
- // Wrap free() in a function to thwart Clang's -Wfree-nonheap-object warning.
- static void callFree(void *ptr) {
- free(ptr);
- }
- TEST(ProcessMemoryTest, MacTerminateOnHeapCorruption) {
- #if BUILDFLAG(USE_ALLOCATOR_SHIM)
- base::allocator::InitializeAllocatorShim();
- #endif
- // Assert that freeing an unallocated pointer will crash the process.
- char buf[9];
- asm("" : "=m"(buf)); // Prevent clang from being too smart.
- #if ARCH_CPU_64_BITS
- // On 64 bit Macs, the malloc system automatically abort()s on heap corruption
- // but does not output anything.
- ASSERT_DEATH(callFree(buf), "");
- #elif defined(ADDRESS_SANITIZER)
- // AddressSanitizer replaces malloc() and prints a different error message on
- // heap corruption.
- ASSERT_DEATH(callFree(buf), "attempting free on address which "
- "was not malloc\\(\\)-ed");
- #else
- ADD_FAILURE() << "This test is not supported in this build configuration.";
- #endif
- #if BUILDFLAG(USE_ALLOCATOR_SHIM)
- base::allocator::UninterceptMallocZonesForTesting();
- #endif
- }
- #endif // BUILDFLAG(IS_MAC)
- TEST(MemoryTest, AllocatorShimWorking) {
- #if BUILDFLAG(IS_MAC)
- #if BUILDFLAG(USE_ALLOCATOR_SHIM)
- base::allocator::InitializeAllocatorShim();
- #endif
- base::allocator::InterceptAllocationsMac();
- #endif
- ASSERT_TRUE(base::allocator::IsAllocatorInitialized());
- #if BUILDFLAG(IS_MAC)
- base::allocator::UninterceptMallocZonesForTesting();
- #endif
- }
- // OpenBSD does not support these tests. Don't test these on ASan/TSan/MSan
- // configurations: only test the real allocator.
- #if !BUILDFLAG(IS_OPENBSD) && BUILDFLAG(USE_ALLOCATOR_SHIM) && \
- !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
- namespace {
- #if BUILDFLAG(IS_WIN)
- // Windows raises an exception in order to make the exit code unique to OOM.
- #define ASSERT_OOM_DEATH(statement) \
- ASSERT_EXIT(statement, \
- testing::ExitedWithCode(base::win::kOomExceptionCode), "")
- #else
- #define ASSERT_OOM_DEATH(statement) ASSERT_DEATH(statement, "")
- #endif // BUILDFLAG(IS_WIN)
- } // namespace
- class OutOfMemoryTest : public testing::Test {
- public:
- OutOfMemoryTest()
- : value_(nullptr),
- // 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() -
- 3 * base::GetPageSize()),
- // A test size that is > 2Gb and will cause the allocators to reject
- // the allocation due to security restrictions. See crbug.com/169327.
- insecure_test_size_(std::numeric_limits<int>::max()),
- signed_test_size_(std::numeric_limits<ssize_t>::max()) {}
- protected:
- void* value_;
- size_t test_size_;
- size_t insecure_test_size_;
- ssize_t signed_test_size_;
- };
- class OutOfMemoryDeathTest : public OutOfMemoryTest {
- public:
- void SetUpInDeathAssert() {
- #if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_ALLOCATOR_SHIM)
- base::allocator::InitializeAllocatorShim();
- #endif
- // Must call EnableTerminationOnOutOfMemory() because that is called from
- // chrome's main function and therefore hasn't been called yet.
- // Since this call may result in another thread being created and death
- // tests shouldn't be started in a multithread environment, this call
- // should be done inside of the ASSERT_DEATH.
- base::EnableTerminationOnOutOfMemory();
- }
- #if BUILDFLAG(IS_MAC)
- void TearDown() override {
- base::allocator::UninterceptMallocZonesForTesting();
- }
- #endif
- // These tests don't work properly on old x86 Android; crbug.com/1181112
- bool ShouldSkipTest() {
- #if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_X86)
- return base::android::BuildInfo::GetInstance()->sdk_int() <
- base::android::SDK_VERSION_NOUGAT;
- #else
- return false;
- #endif
- }
- };
- TEST_F(OutOfMemoryDeathTest, New) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = operator new(test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, NewArray) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = new char[test_size_];
- });
- }
- TEST_F(OutOfMemoryDeathTest, Malloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc(test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, Realloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = realloc(nullptr, test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, Calloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = calloc(1024, test_size_ / 1024L);
- });
- }
- TEST_F(OutOfMemoryDeathTest, AlignedAlloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = base::AlignedAlloc(test_size_, 8);
- });
- }
- // POSIX does not define an aligned realloc function.
- #if BUILDFLAG(IS_WIN)
- TEST_F(OutOfMemoryDeathTest, AlignedRealloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = _aligned_realloc(nullptr, test_size_, 8);
- });
- }
- namespace {
- constexpr uint32_t kUnhandledExceptionExitCode = 0xBADA55;
- // This unhandled exception filter exits the process with an exit code distinct
- // from the exception code. This is to verify that the out of memory new handler
- // causes an unhandled exception.
- LONG WINAPI ExitingUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo) {
- _exit(kUnhandledExceptionExitCode);
- }
- } // namespace
- TEST_F(OutOfMemoryDeathTest, NewHandlerGeneratesUnhandledException) {
- ASSERT_EXIT(
- {
- SetUpInDeathAssert();
- SetUnhandledExceptionFilter(&ExitingUnhandledExceptionFilter);
- value_ = new char[test_size_];
- },
- testing::ExitedWithCode(kUnhandledExceptionExitCode), "");
- }
- #endif // BUILDFLAG(IS_WIN)
- // OS X has no 2Gb allocation limit.
- // See https://crbug.com/169327.
- #if !BUILDFLAG(IS_MAC)
- TEST_F(OutOfMemoryDeathTest, SecurityNew) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = operator new(insecure_test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityNewArray) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = new char[insecure_test_size_];
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityMalloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc(insecure_test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityRealloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = realloc(nullptr, insecure_test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityCalloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = calloc(1024, insecure_test_size_ / 1024L);
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityAlignedAlloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = base::AlignedAlloc(insecure_test_size_, 8);
- });
- }
- // POSIX does not define an aligned realloc function.
- #if BUILDFLAG(IS_WIN)
- TEST_F(OutOfMemoryDeathTest, SecurityAlignedRealloc) {
- if (ShouldSkipTest()) {
- return;
- }
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = _aligned_realloc(nullptr, insecure_test_size_, 8);
- });
- }
- #endif // BUILDFLAG(IS_WIN)
- #endif // !BUILDFLAG(IS_MAC)
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- TEST_F(OutOfMemoryDeathTest, Valloc) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = valloc(test_size_);
- EXPECT_TRUE(value_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityValloc) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = valloc(insecure_test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, Pvalloc) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = pvalloc(test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, SecurityPvalloc) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = pvalloc(insecure_test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, Memalign) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = memalign(4, test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, ViaSharedLibraries) {
- // This tests that the run-time symbol resolution is overriding malloc for
- // shared libraries as well as for our code.
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = MallocWrapper(test_size_);
- });
- }
- #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- // Android doesn't implement posix_memalign().
- #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
- TEST_F(OutOfMemoryDeathTest, Posix_memalign) {
- // Grab the return value of posix_memalign to silence a compiler warning
- // about unused return values. We don't actually care about the return
- // value, since we're asserting death.
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- EXPECT_EQ(ENOMEM, posix_memalign(&value_, 8, test_size_));
- });
- }
- #endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
- #if BUILDFLAG(IS_MAC)
- // Purgeable zone tests
- TEST_F(OutOfMemoryDeathTest, MallocPurgeable) {
- malloc_zone_t* zone = malloc_default_purgeable_zone();
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc_zone_malloc(zone, test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, ReallocPurgeable) {
- malloc_zone_t* zone = malloc_default_purgeable_zone();
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc_zone_realloc(zone, nullptr, test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, CallocPurgeable) {
- malloc_zone_t* zone = malloc_default_purgeable_zone();
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc_zone_calloc(zone, 1024, test_size_ / 1024L);
- });
- }
- TEST_F(OutOfMemoryDeathTest, VallocPurgeable) {
- malloc_zone_t* zone = malloc_default_purgeable_zone();
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc_zone_valloc(zone, test_size_);
- });
- }
- TEST_F(OutOfMemoryDeathTest, PosixMemalignPurgeable) {
- malloc_zone_t* zone = malloc_default_purgeable_zone();
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- value_ = malloc_zone_memalign(zone, 8, test_size_);
- });
- }
- // Since these allocation functions take a signed size, it's possible that
- // calling them just once won't be enough to exhaust memory. In the 32-bit
- // environment, it's likely that these allocation attempts will fail because
- // not enough contiguous address space is available. In the 64-bit environment,
- // it's likely that they'll fail because they would require a preposterous
- // amount of (virtual) memory.
- TEST_F(OutOfMemoryDeathTest, CFAllocatorMalloc) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- while ((value_ = base::AllocateViaCFAllocatorMalloc(signed_test_size_))) {
- }
- });
- }
- #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
- // PartitionAlloc-Everywhere does not intercept other malloc zones than the
- // default (the top) malloc zone. Plus,
- // CFAllocatorAllocate(kCFAllocatorSystemDefault, size, 0) does not call the
- // default (the top) malloc zone on macOS 10.xx (does call it on macOS 11 and
- // later though).
- #define MAYBE_CFAllocatorSystemDefault DISABLED_CFAllocatorSystemDefault
- #else
- #define MAYBE_CFAllocatorSystemDefault CFAllocatorSystemDefault
- #endif
- TEST_F(OutOfMemoryDeathTest, MAYBE_CFAllocatorSystemDefault) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- while ((value_ =
- base::AllocateViaCFAllocatorSystemDefault(signed_test_size_))) {
- }
- });
- }
- #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
- // PartitionAlloc-Everywhere does not intercept other malloc zones than the
- // default (the top) malloc zone. Plus,
- // CFAllocatorAllocate(kCFAllocatorMallocZone, size, 0) does not call the
- // default (the top) malloc zone on macOS 10.xx (does call it on macOS 11 and
- // later though).
- #define MAYBE_CFAllocatorMallocZone DISABLED_CFAllocatorMallocZone
- #else
- #define MAYBE_CFAllocatorMallocZone CFAllocatorMallocZone
- #endif
- TEST_F(OutOfMemoryDeathTest, MAYBE_CFAllocatorMallocZone) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- while (
- (value_ = base::AllocateViaCFAllocatorMallocZone(signed_test_size_))) {
- }
- });
- }
- #endif // BUILDFLAG(IS_MAC)
- class OutOfMemoryHandledTest : public OutOfMemoryTest {
- public:
- static const size_t kSafeMallocSize = 512;
- static const size_t kSafeCallocSize = 128;
- static const size_t kSafeCallocItems = 4;
- void SetUp() override {
- 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();
- }
- void TearDown() override {
- #if BUILDFLAG(IS_MAC)
- base::allocator::UninterceptMallocZonesForTesting();
- #endif
- }
- };
- #if BUILDFLAG(IS_WIN)
- namespace {
- DWORD HandleOutOfMemoryException(EXCEPTION_POINTERS* exception_ptrs,
- size_t expected_size) {
- EXPECT_EQ(base::win::kOomExceptionCode,
- exception_ptrs->ExceptionRecord->ExceptionCode);
- EXPECT_LE(1U, exception_ptrs->ExceptionRecord->NumberParameters);
- EXPECT_EQ(expected_size,
- exception_ptrs->ExceptionRecord->ExceptionInformation[0]);
- return EXCEPTION_EXECUTE_HANDLER;
- }
- } // namespace
- TEST_F(OutOfMemoryTest, TerminateBecauseOutOfMemoryReportsAllocSize) {
- // On Windows, TerminateBecauseOutOfMemory reports the attempted allocation
- // size in the exception raised.
- #if defined(ARCH_CPU_64_BITS)
- // Test with a size larger than 32 bits on 64 bit machines.
- const size_t kAttemptedAllocationSize = 0xBADA55F00DULL;
- #else
- const size_t kAttemptedAllocationSize = 0xBADA55;
- #endif
- __try {
- base::TerminateBecauseOutOfMemory(kAttemptedAllocationSize);
- } __except (HandleOutOfMemoryException(GetExceptionInformation(),
- kAttemptedAllocationSize)) {
- }
- }
- #endif // BUILDFLAG(IS_WIN)
- #if defined(ARCH_CPU_32_BITS) && \
- (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
- void TestAllocationsReleaseReservation(void* (*alloc_fn)(size_t),
- void (*free_fn)(void*)) {
- partition_alloc::ReleaseReservation();
- base::EnableTerminationOnOutOfMemory();
- constexpr size_t kMiB = 1 << 20;
- constexpr size_t kReservationSize = 512 * kMiB; // MiB.
- size_t reservation_size = kReservationSize;
- while (!partition_alloc::ReserveAddressSpace(reservation_size)) {
- reservation_size -= 16 * kMiB;
- }
- ASSERT_TRUE(partition_alloc::HasReservationForTesting());
- ASSERT_GT(reservation_size, 0u);
- // Allocate a large area at a time to bump into address space exhaustion
- // before other limits. It is important not to do a larger allocation, to
- // verify that we can allocate without removing the reservation. On the other
- // hand, must be large enough to make the underlying implementation call
- // mmap()/VirtualAlloc().
- size_t allocation_size = reservation_size / 2;
- std::vector<void*> areas;
- // Pre-reserve the vector to make sure that we don't hit the address space
- // limit while resizing the array.
- areas.reserve(((2 * 4096 * kMiB) / allocation_size) + 1);
- while (true) {
- void* area = alloc_fn(allocation_size / 2);
- ASSERT_TRUE(area);
- areas.push_back(area);
- // Working as intended, the allocation was successful, and the reservation
- // was dropped instead of crashing.
- //
- // Meaning that the test is either successful, or crashes.
- if (!partition_alloc::HasReservationForTesting())
- break;
- }
- EXPECT_GE(areas.size(), 2u)
- << "Should be able to allocate without releasing the reservation";
- for (void* ptr : areas)
- free_fn(ptr);
- }
- TEST_F(OutOfMemoryHandledTest, MallocReleasesReservation) {
- TestAllocationsReleaseReservation(malloc, free);
- }
- TEST_F(OutOfMemoryHandledTest, NewReleasesReservation) {
- TestAllocationsReleaseReservation(
- [](size_t size) { return static_cast<void*>(new char[size]); },
- [](void* ptr) { delete[] static_cast<char*>(ptr); });
- }
- #endif // defined(ARCH_CPU_32_BITS) && (BUILDFLAG(IS_WIN) ||
- // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
- #if BUILDFLAG(IS_ANDROID)
- // Android's allocator does not allow overcommits, so very large
- // UncheckedMallocs will yield OOM errors.
- // TODO(crbug.com/1112840): Fails on some Android bots.
- #define MAYBE_UncheckedMallocDies DISABLED_UncheckedMallocDies
- #define MAYBE_UncheckedCallocDies DISABLED_UncheckedCallocDies
- TEST_F(OutOfMemoryDeathTest, MAYBE_UncheckedMallocDies) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- void* data;
- std::ignore = base::UncheckedMalloc(test_size_, &data);
- // Death expected here.
- });
- }
- TEST_F(OutOfMemoryDeathTest, MAYBE_UncheckedCallocDies) {
- ASSERT_OOM_DEATH({
- SetUpInDeathAssert();
- void* data;
- std::ignore = base::UncheckedCalloc(1, test_size_, &data);
- // Death expected here.
- });
- }
- #else
- TEST_F(OutOfMemoryHandledTest, UncheckedMalloc) {
- EXPECT_TRUE(base::UncheckedMalloc(kSafeMallocSize, &value_));
- EXPECT_TRUE(value_ != nullptr);
- base::UncheckedFree(value_);
- EXPECT_FALSE(base::UncheckedMalloc(test_size_, &value_));
- EXPECT_TRUE(value_ == nullptr);
- }
- TEST_F(OutOfMemoryHandledTest, UncheckedCalloc) {
- EXPECT_TRUE(base::UncheckedCalloc(1, kSafeMallocSize, &value_));
- EXPECT_TRUE(value_ != nullptr);
- const char* bytes = static_cast<const char*>(value_);
- for (size_t i = 0; i < kSafeMallocSize; ++i)
- EXPECT_EQ(0, bytes[i]);
- base::UncheckedFree(value_);
- EXPECT_TRUE(
- base::UncheckedCalloc(kSafeCallocItems, kSafeCallocSize, &value_));
- EXPECT_TRUE(value_ != nullptr);
- bytes = static_cast<const char*>(value_);
- for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i)
- EXPECT_EQ(0, bytes[i]);
- base::UncheckedFree(value_);
- EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &value_));
- EXPECT_TRUE(value_ == nullptr);
- }
- #endif // BUILDFLAG(IS_ANDROID)
- #endif // !BUILDFLAG(IS_OPENBSD) && BUILDFLAG(USE_ALLOCATOR_SHIM) &&
- // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
|