test/util_allocator.cpp

Mon, 08 Aug 2022 17:12:00 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 08 Aug 2022 17:12:00 +0200
changeset 572
f0f99dd06d9f
parent 571
f83583a0bbac
child 642
98c90759f69e
permissions
-rw-r--r--

#201 - remove dangerous allocator config

There is no plausible use case, except using the testing
allocator in the test case, and having the possibility to
specify any allocator (including another mempool) causes
more harm than good.

universe@422 1 /*
universe@422 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@422 3 *
universe@422 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@422 5 *
universe@422 6 * Redistribution and use in source and binary forms, with or without
universe@422 7 * modification, are permitted provided that the following conditions are met:
universe@422 8 *
universe@422 9 * 1. Redistributions of source code must retain the above copyright
universe@422 10 * notice, this list of conditions and the following disclaimer.
universe@422 11 *
universe@422 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@422 13 * notice, this list of conditions and the following disclaimer in the
universe@422 14 * documentation and/or other materials provided with the distribution.
universe@422 15 *
universe@422 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@422 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@422 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@422 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@422 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@422 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@422 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@422 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@422 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@422 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@422 26 * POSSIBILITY OF SUCH DAMAGE.
universe@422 27 */
universe@422 28
universe@422 29 #include "util_allocator.h"
universe@422 30
universe@422 31 void *cx_malloc_testing(void *d, size_t n) {
universe@518 32 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 33 void *ptr = malloc(n);
universe@422 34 data->alloc_total++;
universe@518 35 if (ptr == nullptr) {
universe@422 36 data->alloc_failed++;
universe@422 37 } else {
universe@518 38 data->tracked.insert(ptr);
universe@422 39 }
universe@422 40 return ptr;
universe@422 41 }
universe@422 42
universe@422 43 void *cx_realloc_testing(void *d, void *mem, size_t n) {
universe@518 44 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 45 void *ptr = realloc(mem, n);
universe@422 46 if (ptr == mem) {
universe@422 47 return ptr;
universe@422 48 } else {
universe@422 49 data->alloc_total++;
universe@518 50 if (ptr == nullptr) {
universe@422 51 data->alloc_failed++;
universe@422 52 } else {
universe@422 53 data->free_total++;
universe@518 54 if (data->tracked.erase(mem) == 0) {
universe@422 55 data->free_failed++;
universe@422 56 }
universe@518 57 data->tracked.insert(ptr);
universe@422 58 }
universe@422 59 return ptr;
universe@422 60 }
universe@422 61 }
universe@422 62
universe@422 63 void *cx_calloc_testing(void *d, size_t nelem, size_t n) {
universe@518 64 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 65 void *ptr = calloc(nelem, n);
universe@422 66 data->alloc_total++;
universe@518 67 if (ptr == nullptr) {
universe@422 68 data->alloc_failed++;
universe@422 69 } else {
universe@518 70 data->tracked.insert(ptr);
universe@422 71 }
universe@422 72 return ptr;
universe@422 73 }
universe@422 74
universe@422 75 void cx_free_testing(void *d, void *mem) {
universe@518 76 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 77 data->free_total++;
universe@518 78 if (data->tracked.erase(mem) == 0) {
universe@422 79 data->free_failed++;
universe@422 80 // do not even attempt to free mem, because it is likely to segfault
universe@422 81 } else {
universe@422 82 free(mem);
universe@422 83 }
universe@422 84 }
universe@422 85
universe@422 86 cx_allocator_class cx_testing_allocator_class = {
universe@422 87 cx_malloc_testing,
universe@422 88 cx_realloc_testing,
universe@422 89 cx_calloc_testing,
universe@422 90 cx_free_testing
universe@422 91 };
universe@422 92
universe@518 93 CxTestingAllocator::CxTestingAllocator() : CxAllocator() {
universe@518 94 cl = &cx_testing_allocator_class;
universe@518 95 data = this;
universe@422 96 }
universe@422 97
universe@571 98 bool CxTestingAllocator::used() const {
universe@571 99 return alloc_total > 0;
universe@571 100 }
universe@571 101
universe@518 102 bool CxTestingAllocator::verify() const {
universe@518 103 return tracked.empty() && alloc_failed == 0 && free_failed == 0 && alloc_total == free_total;
universe@422 104 }
universe@518 105
universe@518 106 // SELF-TEST
universe@518 107
universe@518 108 #include <gtest/gtest.h>
universe@518 109
universe@518 110 TEST(TestingAllocator, ExpectFree) {
universe@518 111 CxTestingAllocator allocator;
universe@518 112
universe@518 113 ASSERT_TRUE(allocator.verify());
universe@518 114 auto ptr = cxMalloc(&allocator, 16);
universe@518 115 ASSERT_NE(ptr, nullptr);
universe@518 116 EXPECT_FALSE(allocator.verify());
universe@518 117
universe@518 118 cxFree(&allocator, ptr);
universe@518 119 EXPECT_TRUE(allocator.verify());
universe@518 120 }
universe@518 121
universe@518 122 TEST(TestingAllocator, DetectDoubleFree) {
universe@518 123 CxTestingAllocator allocator;
universe@518 124
universe@518 125 ASSERT_TRUE(allocator.verify());
universe@518 126 auto ptr = cxMalloc(&allocator, 16);
universe@518 127 ASSERT_NE(ptr, nullptr);
universe@518 128
universe@518 129 cxFree(&allocator, ptr);
universe@518 130 EXPECT_TRUE(allocator.verify());
universe@518 131 ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
universe@518 132 EXPECT_FALSE(allocator.verify());
universe@518 133 }
universe@518 134
universe@518 135 TEST(TestingAllocator, FreeUntracked) {
universe@518 136 CxTestingAllocator allocator;
universe@518 137
universe@518 138 auto ptr = malloc(16);
universe@518 139 ASSERT_TRUE(allocator.verify());
universe@518 140 ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
universe@518 141 EXPECT_FALSE(allocator.verify());
universe@518 142 ASSERT_NO_FATAL_FAILURE(free(ptr));
universe@518 143 }
universe@518 144
universe@518 145 TEST(TestingAllocator, FullLifecycleWithRealloc) {
universe@518 146 CxTestingAllocator allocator;
universe@518 147 ASSERT_TRUE(allocator.verify());
universe@518 148 auto ptr = cxMalloc(&allocator, 16);
universe@518 149 ASSERT_NE(ptr, nullptr);
universe@518 150 EXPECT_EQ(allocator.tracked.size(), 1);
universe@518 151 ptr = cxRealloc(&allocator, ptr, 256);
universe@518 152 ASSERT_NE(ptr, nullptr);
universe@518 153 EXPECT_EQ(allocator.tracked.size(), 1);
universe@518 154 cxFree(&allocator, ptr);
universe@518 155 EXPECT_TRUE(allocator.verify());
universe@518 156 }
universe@518 157
universe@518 158 TEST(TestingAllocator, CallocInitializes) {
universe@518 159 CxTestingAllocator allocator;
universe@518 160 const char* zeros[16] = {0};
universe@518 161 auto ptr = cxCalloc(&allocator, 16, 1);
universe@518 162 EXPECT_EQ(memcmp(ptr, zeros, 16), 0);
universe@518 163 cxFree(&allocator, ptr);
universe@518 164 EXPECT_TRUE(allocator.verify());
universe@518 165 }

mercurial