fork
Fork of cpputest by
src/CppUTest/MemoryLeakWarningPlugin.cpp@1:4769360130ed, 2014-06-17 (annotated)
- Committer:
- Rohit Grover
- Date:
- Tue Jun 17 15:52:54 2014 +0100
- Revision:
- 1:4769360130ed
- Parent:
- 0:0b799af9d58e
updating to the latest version of cppUtest; tested against nordic's m-kit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Rohit Grover |
1:4769360130ed | 1 | /* |
Rohit Grover |
1:4769360130ed | 2 | * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde |
Rohit Grover |
1:4769360130ed | 3 | * All rights reserved. |
Rohit Grover |
1:4769360130ed | 4 | * |
Rohit Grover |
1:4769360130ed | 5 | * Redistribution and use in source and binary forms, with or without |
Rohit Grover |
1:4769360130ed | 6 | * modification, are permitted provided that the following conditions are met: |
Rohit Grover |
1:4769360130ed | 7 | * * Redistributions of source code must retain the above copyright |
Rohit Grover |
1:4769360130ed | 8 | * notice, this list of conditions and the following disclaimer. |
Rohit Grover |
1:4769360130ed | 9 | * * Redistributions in binary form must reproduce the above copyright |
Rohit Grover |
1:4769360130ed | 10 | * notice, this list of conditions and the following disclaimer in the |
Rohit Grover |
1:4769360130ed | 11 | * documentation and/or other materials provided with the distribution. |
Rohit Grover |
1:4769360130ed | 12 | * * Neither the name of the <organization> nor the |
Rohit Grover |
1:4769360130ed | 13 | * names of its contributors may be used to endorse or promote products |
Rohit Grover |
1:4769360130ed | 14 | * derived from this software without specific prior written permission. |
Rohit Grover |
1:4769360130ed | 15 | * |
Rohit Grover |
1:4769360130ed | 16 | * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY |
Rohit Grover |
1:4769360130ed | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
Rohit Grover |
1:4769360130ed | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
Rohit Grover |
1:4769360130ed | 19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY |
Rohit Grover |
1:4769360130ed | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
Rohit Grover |
1:4769360130ed | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
Rohit Grover |
1:4769360130ed | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
Rohit Grover |
1:4769360130ed | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
Rohit Grover |
1:4769360130ed | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
Rohit Grover |
1:4769360130ed | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Rohit Grover |
1:4769360130ed | 26 | */ |
Rohit Grover |
1:4769360130ed | 27 | |
Rohit Grover |
1:4769360130ed | 28 | #include "CppUTest/TestHarness.h" |
Rohit Grover |
1:4769360130ed | 29 | #include "CppUTest/MemoryLeakWarningPlugin.h" |
Rohit Grover |
1:4769360130ed | 30 | #include "CppUTest/MemoryLeakDetector.h" |
Rohit Grover |
1:4769360130ed | 31 | #include "CppUTest/TestMemoryAllocator.h" |
Rohit Grover |
1:4769360130ed | 32 | #include "CppUTest/PlatformSpecificFunctions.h" |
Rohit Grover |
1:4769360130ed | 33 | |
Rohit Grover |
1:4769360130ed | 34 | /********** Enabling and disabling for C also *********/ |
Rohit Grover |
1:4769360130ed | 35 | |
Rohit Grover |
1:4769360130ed | 36 | #if CPPUTEST_USE_MEM_LEAK_DETECTION |
Rohit Grover |
1:4769360130ed | 37 | |
Rohit Grover |
1:4769360130ed | 38 | static void* mem_leak_malloc(size_t size, const char* file, int line) |
Rohit Grover |
1:4769360130ed | 39 | { |
Rohit Grover |
1:4769360130ed | 40 | return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentMallocAllocator(), size, file, line, true); |
Rohit Grover |
1:4769360130ed | 41 | } |
Rohit Grover |
1:4769360130ed | 42 | |
Rohit Grover |
1:4769360130ed | 43 | static void mem_leak_free(void* buffer, const char* file, int line) |
Rohit Grover |
1:4769360130ed | 44 | { |
Rohit Grover |
1:4769360130ed | 45 | MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) buffer); |
Rohit Grover |
1:4769360130ed | 46 | MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentMallocAllocator(), (char*) buffer, file, line, true); |
Rohit Grover |
1:4769360130ed | 47 | } |
Rohit Grover |
1:4769360130ed | 48 | |
Rohit Grover |
1:4769360130ed | 49 | static void* mem_leak_realloc(void* memory, size_t size, const char* file, int line) |
Rohit Grover |
1:4769360130ed | 50 | { |
Rohit Grover |
1:4769360130ed | 51 | return MemoryLeakWarningPlugin::getGlobalDetector()->reallocMemory(getCurrentMallocAllocator(), (char*) memory, size, file, line, true); |
Rohit Grover |
1:4769360130ed | 52 | } |
Rohit Grover |
1:4769360130ed | 53 | |
Rohit Grover |
1:4769360130ed | 54 | #endif |
Rohit Grover |
1:4769360130ed | 55 | |
Rohit Grover |
1:4769360130ed | 56 | static void* normal_malloc(size_t size, const char*, int) |
Rohit Grover |
1:4769360130ed | 57 | { |
Rohit Grover |
1:4769360130ed | 58 | return PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 59 | } |
Rohit Grover |
1:4769360130ed | 60 | |
Rohit Grover |
1:4769360130ed | 61 | static void* normal_realloc(void* memory, size_t size, const char*, int) |
Rohit Grover |
1:4769360130ed | 62 | { |
Rohit Grover |
1:4769360130ed | 63 | return PlatformSpecificRealloc(memory, size); |
Rohit Grover |
1:4769360130ed | 64 | } |
Rohit Grover |
1:4769360130ed | 65 | |
Rohit Grover |
1:4769360130ed | 66 | static void normal_free(void* buffer, const char*, int) |
Rohit Grover |
1:4769360130ed | 67 | { |
Rohit Grover |
1:4769360130ed | 68 | PlatformSpecificFree(buffer); |
Rohit Grover |
1:4769360130ed | 69 | } |
Rohit Grover |
1:4769360130ed | 70 | |
Rohit Grover |
1:4769360130ed | 71 | #if CPPUTEST_USE_MEM_LEAK_DETECTION |
Rohit Grover |
1:4769360130ed | 72 | static void *(*malloc_fptr)(size_t size, const char* file, int line) = mem_leak_malloc; |
Rohit Grover |
1:4769360130ed | 73 | static void (*free_fptr)(void* mem, const char* file, int line) = mem_leak_free; |
Rohit Grover |
1:4769360130ed | 74 | static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = mem_leak_realloc; |
Rohit Grover |
1:4769360130ed | 75 | #else |
Rohit Grover |
1:4769360130ed | 76 | static void *(*malloc_fptr)(size_t size, const char* file, int line) = normal_malloc; |
Rohit Grover |
1:4769360130ed | 77 | static void (*free_fptr)(void* mem, const char* file, int line) = normal_free; |
Rohit Grover |
1:4769360130ed | 78 | static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = normal_realloc; |
Rohit Grover |
1:4769360130ed | 79 | #endif |
Rohit Grover |
1:4769360130ed | 80 | |
Rohit Grover |
1:4769360130ed | 81 | void* cpputest_malloc_location_with_leak_detection(size_t size, const char* file, int line) |
Rohit Grover |
1:4769360130ed | 82 | { |
Rohit Grover |
1:4769360130ed | 83 | return malloc_fptr(size, file, line); |
Rohit Grover |
1:4769360130ed | 84 | } |
Rohit Grover |
1:4769360130ed | 85 | |
Rohit Grover |
1:4769360130ed | 86 | void* cpputest_realloc_location_with_leak_detection(void* memory, size_t size, const char* file, int line) |
Rohit Grover |
1:4769360130ed | 87 | { |
Rohit Grover |
1:4769360130ed | 88 | return realloc_fptr(memory, size, file, line); |
Rohit Grover |
1:4769360130ed | 89 | } |
Rohit Grover |
1:4769360130ed | 90 | |
Rohit Grover |
1:4769360130ed | 91 | void cpputest_free_location_with_leak_detection(void* buffer, const char* file, int line) |
Rohit Grover |
1:4769360130ed | 92 | { |
Rohit Grover |
1:4769360130ed | 93 | free_fptr(buffer, file, line); |
Rohit Grover |
1:4769360130ed | 94 | } |
Rohit Grover |
1:4769360130ed | 95 | |
Rohit Grover |
1:4769360130ed | 96 | /********** C++ *************/ |
Rohit Grover |
1:4769360130ed | 97 | |
Rohit Grover |
1:4769360130ed | 98 | #if CPPUTEST_USE_MEM_LEAK_DETECTION |
Rohit Grover |
1:4769360130ed | 99 | #undef new |
Rohit Grover |
1:4769360130ed | 100 | |
Rohit Grover |
1:4769360130ed | 101 | #if CPPUTEST_USE_STD_CPP_LIB |
Rohit Grover |
1:4769360130ed | 102 | #define UT_THROW_BAD_ALLOC_WHEN_NULL(memory) if (memory == NULL) throw std::bad_alloc(); |
Rohit Grover |
1:4769360130ed | 103 | #else |
Rohit Grover |
1:4769360130ed | 104 | #define UT_THROW_BAD_ALLOC_WHEN_NULL(memory) |
Rohit Grover |
1:4769360130ed | 105 | #endif |
Rohit Grover |
1:4769360130ed | 106 | |
Rohit Grover |
1:4769360130ed | 107 | static void* mem_leak_operator_new (size_t size) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 108 | { |
Rohit Grover |
1:4769360130ed | 109 | void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size); |
Rohit Grover |
1:4769360130ed | 110 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 111 | return memory; |
Rohit Grover |
1:4769360130ed | 112 | } |
Rohit Grover |
1:4769360130ed | 113 | |
Rohit Grover |
1:4769360130ed | 114 | static void* mem_leak_operator_new_nothrow (size_t size) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 115 | { |
Rohit Grover |
1:4769360130ed | 116 | return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size); |
Rohit Grover |
1:4769360130ed | 117 | } |
Rohit Grover |
1:4769360130ed | 118 | |
Rohit Grover |
1:4769360130ed | 119 | static void* mem_leak_operator_new_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 120 | { |
Rohit Grover |
1:4769360130ed | 121 | void *memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size, (char*) file, line); |
Rohit Grover |
1:4769360130ed | 122 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 123 | return memory; |
Rohit Grover |
1:4769360130ed | 124 | } |
Rohit Grover |
1:4769360130ed | 125 | |
Rohit Grover |
1:4769360130ed | 126 | static void* mem_leak_operator_new_array (size_t size) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 127 | { |
Rohit Grover |
1:4769360130ed | 128 | void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size); |
Rohit Grover |
1:4769360130ed | 129 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 130 | return memory; |
Rohit Grover |
1:4769360130ed | 131 | } |
Rohit Grover |
1:4769360130ed | 132 | |
Rohit Grover |
1:4769360130ed | 133 | static void* mem_leak_operator_new_array_nothrow (size_t size) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 134 | { |
Rohit Grover |
1:4769360130ed | 135 | return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size); |
Rohit Grover |
1:4769360130ed | 136 | } |
Rohit Grover |
1:4769360130ed | 137 | |
Rohit Grover |
1:4769360130ed | 138 | static void* mem_leak_operator_new_array_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 139 | { |
Rohit Grover |
1:4769360130ed | 140 | void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size, (char*) file, line); |
Rohit Grover |
1:4769360130ed | 141 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 142 | return memory; |
Rohit Grover |
1:4769360130ed | 143 | } |
Rohit Grover |
1:4769360130ed | 144 | |
Rohit Grover |
1:4769360130ed | 145 | static void mem_leak_operator_delete (void* mem) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 146 | { |
Rohit Grover |
1:4769360130ed | 147 | MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem); |
Rohit Grover |
1:4769360130ed | 148 | MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewAllocator(), (char*) mem); |
Rohit Grover |
1:4769360130ed | 149 | } |
Rohit Grover |
1:4769360130ed | 150 | |
Rohit Grover |
1:4769360130ed | 151 | static void mem_leak_operator_delete_array (void* mem) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 152 | { |
Rohit Grover |
1:4769360130ed | 153 | MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem); |
Rohit Grover |
1:4769360130ed | 154 | MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewArrayAllocator(), (char*) mem); |
Rohit Grover |
1:4769360130ed | 155 | } |
Rohit Grover |
1:4769360130ed | 156 | |
Rohit Grover |
1:4769360130ed | 157 | static void* normal_operator_new (size_t size) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 158 | { |
Rohit Grover |
1:4769360130ed | 159 | void* memory = PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 160 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 161 | return memory; |
Rohit Grover |
1:4769360130ed | 162 | } |
Rohit Grover |
1:4769360130ed | 163 | |
Rohit Grover |
1:4769360130ed | 164 | static void* normal_operator_new_nothrow (size_t size) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 165 | { |
Rohit Grover |
1:4769360130ed | 166 | return PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 167 | } |
Rohit Grover |
1:4769360130ed | 168 | |
Rohit Grover |
1:4769360130ed | 169 | static void* normal_operator_new_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 170 | { |
Rohit Grover |
1:4769360130ed | 171 | void* memory = PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 172 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 173 | return memory; |
Rohit Grover |
1:4769360130ed | 174 | } |
Rohit Grover |
1:4769360130ed | 175 | |
Rohit Grover |
1:4769360130ed | 176 | static void* normal_operator_new_array (size_t size) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 177 | { |
Rohit Grover |
1:4769360130ed | 178 | void* memory = PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 179 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 180 | return memory; |
Rohit Grover |
1:4769360130ed | 181 | } |
Rohit Grover |
1:4769360130ed | 182 | |
Rohit Grover |
1:4769360130ed | 183 | static void* normal_operator_new_array_nothrow (size_t size) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 184 | { |
Rohit Grover |
1:4769360130ed | 185 | return PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 186 | } |
Rohit Grover |
1:4769360130ed | 187 | |
Rohit Grover |
1:4769360130ed | 188 | static void* normal_operator_new_array_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 189 | { |
Rohit Grover |
1:4769360130ed | 190 | void* memory = PlatformSpecificMalloc(size); |
Rohit Grover |
1:4769360130ed | 191 | UT_THROW_BAD_ALLOC_WHEN_NULL(memory); |
Rohit Grover |
1:4769360130ed | 192 | return memory; |
Rohit Grover |
1:4769360130ed | 193 | } |
Rohit Grover |
1:4769360130ed | 194 | |
Rohit Grover |
1:4769360130ed | 195 | static void normal_operator_delete (void* mem) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 196 | { |
Rohit Grover |
1:4769360130ed | 197 | PlatformSpecificFree(mem); |
Rohit Grover |
1:4769360130ed | 198 | } |
Rohit Grover |
1:4769360130ed | 199 | |
Rohit Grover |
1:4769360130ed | 200 | static void normal_operator_delete_array (void* mem) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 201 | { |
Rohit Grover |
1:4769360130ed | 202 | PlatformSpecificFree(mem); |
Rohit Grover |
1:4769360130ed | 203 | } |
Rohit Grover |
1:4769360130ed | 204 | |
Rohit Grover |
1:4769360130ed | 205 | static void *(*operator_new_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new; |
Rohit Grover |
1:4769360130ed | 206 | static void *(*operator_new_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_nothrow; |
Rohit Grover |
1:4769360130ed | 207 | static void *(*operator_new_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_debug; |
Rohit Grover |
1:4769360130ed | 208 | static void *(*operator_new_array_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array; |
Rohit Grover |
1:4769360130ed | 209 | static void *(*operator_new_array_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_array_nothrow; |
Rohit Grover |
1:4769360130ed | 210 | static void *(*operator_new_array_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array_debug; |
Rohit Grover |
1:4769360130ed | 211 | static void (*operator_delete_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete; |
Rohit Grover |
1:4769360130ed | 212 | static void (*operator_delete_array_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete_array; |
Rohit Grover |
1:4769360130ed | 213 | |
Rohit Grover |
1:4769360130ed | 214 | void* operator new(size_t size) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 215 | { |
Rohit Grover |
1:4769360130ed | 216 | return operator_new_fptr(size); |
Rohit Grover |
1:4769360130ed | 217 | } |
Rohit Grover |
1:4769360130ed | 218 | |
Rohit Grover |
1:4769360130ed | 219 | void* operator new(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 220 | { |
Rohit Grover |
1:4769360130ed | 221 | return operator_new_debug_fptr(size, file, line); |
Rohit Grover |
1:4769360130ed | 222 | } |
Rohit Grover |
1:4769360130ed | 223 | |
Rohit Grover |
1:4769360130ed | 224 | void operator delete(void* mem) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 225 | { |
Rohit Grover |
1:4769360130ed | 226 | operator_delete_fptr(mem); |
Rohit Grover |
1:4769360130ed | 227 | } |
Rohit Grover |
1:4769360130ed | 228 | |
Rohit Grover |
1:4769360130ed | 229 | void operator delete(void* mem, const char*, int) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 230 | { |
Rohit Grover |
1:4769360130ed | 231 | operator_delete_fptr(mem); |
Rohit Grover |
1:4769360130ed | 232 | } |
Rohit Grover |
1:4769360130ed | 233 | |
Rohit Grover |
1:4769360130ed | 234 | void* operator new[](size_t size) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 235 | { |
Rohit Grover |
1:4769360130ed | 236 | return operator_new_array_fptr(size); |
Rohit Grover |
1:4769360130ed | 237 | } |
Rohit Grover |
1:4769360130ed | 238 | |
Rohit Grover |
1:4769360130ed | 239 | void* operator new [](size_t size, const char* file, int line) UT_THROW(std::bad_alloc) |
Rohit Grover |
1:4769360130ed | 240 | { |
Rohit Grover |
1:4769360130ed | 241 | return operator_new_array_debug_fptr(size, file, line); |
Rohit Grover |
1:4769360130ed | 242 | } |
Rohit Grover |
1:4769360130ed | 243 | |
Rohit Grover |
1:4769360130ed | 244 | void operator delete[](void* mem) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 245 | { |
Rohit Grover |
1:4769360130ed | 246 | operator_delete_array_fptr(mem); |
Rohit Grover |
1:4769360130ed | 247 | } |
Rohit Grover |
1:4769360130ed | 248 | |
Rohit Grover |
1:4769360130ed | 249 | void operator delete[](void* mem, const char*, int) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 250 | { |
Rohit Grover |
1:4769360130ed | 251 | operator_delete_array_fptr(mem); |
Rohit Grover |
1:4769360130ed | 252 | } |
Rohit Grover |
1:4769360130ed | 253 | |
Rohit Grover |
1:4769360130ed | 254 | |
Rohit Grover |
1:4769360130ed | 255 | #if CPPUTEST_USE_STD_CPP_LIB |
Rohit Grover |
1:4769360130ed | 256 | |
Rohit Grover |
1:4769360130ed | 257 | void* operator new(size_t size, const std::nothrow_t&) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 258 | { |
Rohit Grover |
1:4769360130ed | 259 | return operator_new_nothrow_fptr(size); |
Rohit Grover |
1:4769360130ed | 260 | } |
Rohit Grover |
1:4769360130ed | 261 | |
Rohit Grover |
1:4769360130ed | 262 | void* operator new[](size_t size, const std::nothrow_t&) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 263 | { |
Rohit Grover |
1:4769360130ed | 264 | return operator_new_array_nothrow_fptr(size); |
Rohit Grover |
1:4769360130ed | 265 | } |
Rohit Grover |
1:4769360130ed | 266 | |
Rohit Grover |
1:4769360130ed | 267 | #else |
Rohit Grover |
1:4769360130ed | 268 | |
Rohit Grover |
1:4769360130ed | 269 | /* Have a similar method. This avoid unused operator_new_nothrow_fptr warning */ |
Rohit Grover |
1:4769360130ed | 270 | |
Rohit Grover |
1:4769360130ed | 271 | extern void* operator_new_nothrow(size_t size) UT_NOTHROW; |
Rohit Grover |
1:4769360130ed | 272 | extern void* operator_new_array_nothrow(size_t size) UT_NOTHROW; |
Rohit Grover |
1:4769360130ed | 273 | |
Rohit Grover |
1:4769360130ed | 274 | void* operator_new_nothrow(size_t size) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 275 | { |
Rohit Grover |
1:4769360130ed | 276 | return operator_new_nothrow_fptr(size); |
Rohit Grover |
1:4769360130ed | 277 | } |
Rohit Grover |
1:4769360130ed | 278 | |
Rohit Grover |
1:4769360130ed | 279 | void* operator_new_array_nothrow(size_t size) UT_NOTHROW |
Rohit Grover |
1:4769360130ed | 280 | { |
Rohit Grover |
1:4769360130ed | 281 | return operator_new_array_nothrow_fptr(size); |
Rohit Grover |
1:4769360130ed | 282 | } |
Rohit Grover |
1:4769360130ed | 283 | |
Rohit Grover |
1:4769360130ed | 284 | #endif |
Rohit Grover |
1:4769360130ed | 285 | #endif |
Rohit Grover |
1:4769360130ed | 286 | |
Rohit Grover |
1:4769360130ed | 287 | void MemoryLeakWarningPlugin::turnOffNewDeleteOverloads() |
Rohit Grover |
1:4769360130ed | 288 | { |
Rohit Grover |
1:4769360130ed | 289 | #if CPPUTEST_USE_MEM_LEAK_DETECTION |
Rohit Grover |
1:4769360130ed | 290 | operator_new_fptr = normal_operator_new; |
Rohit Grover |
1:4769360130ed | 291 | operator_new_nothrow_fptr = normal_operator_new_nothrow; |
Rohit Grover |
1:4769360130ed | 292 | operator_new_debug_fptr = normal_operator_new_debug; |
Rohit Grover |
1:4769360130ed | 293 | operator_new_array_fptr = normal_operator_new_array; |
Rohit Grover |
1:4769360130ed | 294 | operator_new_array_nothrow_fptr = normal_operator_new_array_nothrow; |
Rohit Grover |
1:4769360130ed | 295 | operator_new_array_debug_fptr = normal_operator_new_array_debug; |
Rohit Grover |
1:4769360130ed | 296 | operator_delete_fptr = normal_operator_delete; |
Rohit Grover |
1:4769360130ed | 297 | operator_delete_array_fptr = normal_operator_delete_array; |
Rohit Grover |
1:4769360130ed | 298 | malloc_fptr = normal_malloc; |
Rohit Grover |
1:4769360130ed | 299 | realloc_fptr = normal_realloc; |
Rohit Grover |
1:4769360130ed | 300 | free_fptr = normal_free; |
Rohit Grover |
1:4769360130ed | 301 | |
Rohit Grover |
1:4769360130ed | 302 | #endif |
Rohit Grover |
1:4769360130ed | 303 | } |
Rohit Grover |
1:4769360130ed | 304 | |
Rohit Grover |
1:4769360130ed | 305 | void MemoryLeakWarningPlugin::turnOnNewDeleteOverloads() |
Rohit Grover |
1:4769360130ed | 306 | { |
Rohit Grover |
1:4769360130ed | 307 | #if CPPUTEST_USE_MEM_LEAK_DETECTION |
Rohit Grover |
1:4769360130ed | 308 | operator_new_fptr = mem_leak_operator_new; |
Rohit Grover |
1:4769360130ed | 309 | operator_new_nothrow_fptr = mem_leak_operator_new_nothrow; |
Rohit Grover |
1:4769360130ed | 310 | operator_new_debug_fptr = mem_leak_operator_new_debug; |
Rohit Grover |
1:4769360130ed | 311 | operator_new_array_fptr = mem_leak_operator_new_array; |
Rohit Grover |
1:4769360130ed | 312 | operator_new_array_nothrow_fptr = mem_leak_operator_new_array_nothrow; |
Rohit Grover |
1:4769360130ed | 313 | operator_new_array_debug_fptr = mem_leak_operator_new_array_debug; |
Rohit Grover |
1:4769360130ed | 314 | operator_delete_fptr = mem_leak_operator_delete; |
Rohit Grover |
1:4769360130ed | 315 | operator_delete_array_fptr = mem_leak_operator_delete_array; |
Rohit Grover |
1:4769360130ed | 316 | malloc_fptr = mem_leak_malloc; |
Rohit Grover |
1:4769360130ed | 317 | realloc_fptr = mem_leak_realloc; |
Rohit Grover |
1:4769360130ed | 318 | free_fptr = mem_leak_free; |
Rohit Grover |
1:4769360130ed | 319 | #endif |
Rohit Grover |
1:4769360130ed | 320 | } |
Rohit Grover |
1:4769360130ed | 321 | |
Rohit Grover |
1:4769360130ed | 322 | bool MemoryLeakWarningPlugin::areNewDeleteOverloaded() |
Rohit Grover |
1:4769360130ed | 323 | { |
Rohit Grover |
1:4769360130ed | 324 | #if CPPUTEST_USE_MEM_LEAK_DETECTION |
Rohit Grover |
1:4769360130ed | 325 | return operator_new_fptr == mem_leak_operator_new; |
Rohit Grover |
1:4769360130ed | 326 | #else |
Rohit Grover |
1:4769360130ed | 327 | return false; |
Rohit Grover |
1:4769360130ed | 328 | #endif |
Rohit Grover |
1:4769360130ed | 329 | } |
Rohit Grover |
1:4769360130ed | 330 | |
Rohit Grover |
1:4769360130ed | 331 | void crash_on_allocation_number(unsigned alloc_number) |
Rohit Grover |
1:4769360130ed | 332 | { |
Rohit Grover |
1:4769360130ed | 333 | static CrashOnAllocationAllocator crashAllocator; |
Rohit Grover |
1:4769360130ed | 334 | crashAllocator.setNumberToCrashOn(alloc_number); |
Rohit Grover |
1:4769360130ed | 335 | setCurrentMallocAllocator(&crashAllocator); |
Rohit Grover |
1:4769360130ed | 336 | setCurrentNewAllocator(&crashAllocator); |
Rohit Grover |
1:4769360130ed | 337 | setCurrentNewArrayAllocator(&crashAllocator); |
Rohit Grover |
1:4769360130ed | 338 | } |
Rohit Grover |
1:4769360130ed | 339 | |
Rohit Grover |
1:4769360130ed | 340 | class MemoryLeakWarningReporter: public MemoryLeakFailure |
Rohit Grover |
1:4769360130ed | 341 | { |
Rohit Grover |
1:4769360130ed | 342 | public: |
Rohit Grover |
1:4769360130ed | 343 | virtual ~MemoryLeakWarningReporter() |
Rohit Grover |
1:4769360130ed | 344 | { |
Rohit Grover |
1:4769360130ed | 345 | } |
Rohit Grover |
1:4769360130ed | 346 | |
Rohit Grover |
1:4769360130ed | 347 | virtual void fail(char* fail_string) |
Rohit Grover |
1:4769360130ed | 348 | { |
Rohit Grover |
1:4769360130ed | 349 | UtestShell* currentTest = UtestShell::getCurrent(); |
Rohit Grover |
1:4769360130ed | 350 | currentTest->failWith(FailFailure(currentTest, currentTest->getName().asCharString(), currentTest->getLineNumber(), fail_string), TestTerminatorWithoutExceptions()); |
Rohit Grover |
1:4769360130ed | 351 | } |
Rohit Grover |
1:4769360130ed | 352 | }; |
Rohit Grover |
1:4769360130ed | 353 | |
Rohit Grover |
1:4769360130ed | 354 | static MemoryLeakFailure* globalReporter = 0; |
Rohit Grover |
1:4769360130ed | 355 | static MemoryLeakDetector* globalDetector = 0; |
Rohit Grover |
1:4769360130ed | 356 | |
Rohit Grover |
1:4769360130ed | 357 | MemoryLeakDetector* MemoryLeakWarningPlugin::getGlobalDetector() |
Rohit Grover |
1:4769360130ed | 358 | { |
Rohit Grover |
1:4769360130ed | 359 | if (globalDetector == 0) { |
Rohit Grover |
1:4769360130ed | 360 | bool newDeleteOverloaded = areNewDeleteOverloaded(); |
Rohit Grover |
1:4769360130ed | 361 | turnOffNewDeleteOverloads(); |
Rohit Grover |
1:4769360130ed | 362 | |
Rohit Grover |
1:4769360130ed | 363 | globalReporter = new MemoryLeakWarningReporter; |
Rohit Grover |
1:4769360130ed | 364 | globalDetector = new MemoryLeakDetector(globalReporter); |
Rohit Grover |
1:4769360130ed | 365 | |
Rohit Grover |
1:4769360130ed | 366 | if (newDeleteOverloaded) turnOnNewDeleteOverloads(); |
Rohit Grover |
1:4769360130ed | 367 | } |
Rohit Grover |
1:4769360130ed | 368 | return globalDetector; |
Rohit Grover |
1:4769360130ed | 369 | } |
Rohit Grover |
1:4769360130ed | 370 | |
Rohit Grover |
1:4769360130ed | 371 | MemoryLeakFailure* MemoryLeakWarningPlugin::getGlobalFailureReporter() |
Rohit Grover |
1:4769360130ed | 372 | { |
Rohit Grover |
1:4769360130ed | 373 | return globalReporter; |
Rohit Grover |
1:4769360130ed | 374 | } |
Rohit Grover |
1:4769360130ed | 375 | |
Rohit Grover |
1:4769360130ed | 376 | void MemoryLeakWarningPlugin::destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(bool des) |
Rohit Grover |
1:4769360130ed | 377 | { |
Rohit Grover |
1:4769360130ed | 378 | destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_ = des; |
Rohit Grover |
1:4769360130ed | 379 | } |
Rohit Grover |
1:4769360130ed | 380 | |
Rohit Grover |
1:4769360130ed | 381 | void MemoryLeakWarningPlugin::setGlobalDetector(MemoryLeakDetector* detector, MemoryLeakFailure* reporter) |
Rohit Grover |
1:4769360130ed | 382 | { |
Rohit Grover |
1:4769360130ed | 383 | globalDetector = detector; |
Rohit Grover |
1:4769360130ed | 384 | globalReporter = reporter; |
Rohit Grover |
1:4769360130ed | 385 | } |
Rohit Grover |
1:4769360130ed | 386 | |
Rohit Grover |
1:4769360130ed | 387 | void MemoryLeakWarningPlugin::destroyGlobalDetector() |
Rohit Grover |
1:4769360130ed | 388 | { |
Rohit Grover |
1:4769360130ed | 389 | turnOffNewDeleteOverloads(); |
Rohit Grover |
1:4769360130ed | 390 | delete globalDetector; |
Rohit Grover |
1:4769360130ed | 391 | delete globalReporter; |
Rohit Grover |
1:4769360130ed | 392 | globalDetector = NULL; |
Rohit Grover |
1:4769360130ed | 393 | } |
Rohit Grover |
1:4769360130ed | 394 | |
Rohit Grover |
1:4769360130ed | 395 | |
Rohit Grover |
1:4769360130ed | 396 | MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::firstPlugin_ = 0; |
Rohit Grover |
1:4769360130ed | 397 | |
Rohit Grover |
1:4769360130ed | 398 | MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::getFirstPlugin() |
Rohit Grover |
1:4769360130ed | 399 | { |
Rohit Grover |
1:4769360130ed | 400 | return firstPlugin_; |
Rohit Grover |
1:4769360130ed | 401 | } |
Rohit Grover |
1:4769360130ed | 402 | |
Rohit Grover |
1:4769360130ed | 403 | MemoryLeakDetector* MemoryLeakWarningPlugin::getMemoryLeakDetector() |
Rohit Grover |
1:4769360130ed | 404 | { |
Rohit Grover |
1:4769360130ed | 405 | return memLeakDetector_; |
Rohit Grover |
1:4769360130ed | 406 | } |
Rohit Grover |
1:4769360130ed | 407 | |
Rohit Grover |
1:4769360130ed | 408 | void MemoryLeakWarningPlugin::ignoreAllLeaksInTest() |
Rohit Grover |
1:4769360130ed | 409 | { |
Rohit Grover |
1:4769360130ed | 410 | ignoreAllWarnings_ = true; |
Rohit Grover |
1:4769360130ed | 411 | } |
Rohit Grover |
1:4769360130ed | 412 | |
Rohit Grover |
1:4769360130ed | 413 | void MemoryLeakWarningPlugin::expectLeaksInTest(int n) |
Rohit Grover |
1:4769360130ed | 414 | { |
Rohit Grover |
1:4769360130ed | 415 | expectedLeaks_ = n; |
Rohit Grover |
1:4769360130ed | 416 | } |
Rohit Grover |
1:4769360130ed | 417 | |
Rohit Grover |
1:4769360130ed | 418 | MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector) : |
Rohit Grover |
1:4769360130ed | 419 | TestPlugin(name), ignoreAllWarnings_(false), destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_(false), expectedLeaks_(0) |
Rohit Grover |
1:4769360130ed | 420 | { |
Rohit Grover |
1:4769360130ed | 421 | if (firstPlugin_ == 0) firstPlugin_ = this; |
Rohit Grover |
1:4769360130ed | 422 | |
Rohit Grover |
1:4769360130ed | 423 | if (localDetector) memLeakDetector_ = localDetector; |
Rohit Grover |
1:4769360130ed | 424 | else memLeakDetector_ = getGlobalDetector(); |
Rohit Grover |
1:4769360130ed | 425 | |
Rohit Grover |
1:4769360130ed | 426 | memLeakDetector_->enable(); |
Rohit Grover |
1:4769360130ed | 427 | } |
Rohit Grover |
1:4769360130ed | 428 | |
Rohit Grover |
1:4769360130ed | 429 | MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin() |
Rohit Grover |
1:4769360130ed | 430 | { |
Rohit Grover |
1:4769360130ed | 431 | if (destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_) { |
Rohit Grover |
1:4769360130ed | 432 | MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); |
Rohit Grover |
1:4769360130ed | 433 | MemoryLeakWarningPlugin::destroyGlobalDetector(); |
Rohit Grover |
1:4769360130ed | 434 | } |
Rohit Grover |
1:4769360130ed | 435 | } |
Rohit Grover |
1:4769360130ed | 436 | |
Rohit Grover |
1:4769360130ed | 437 | void MemoryLeakWarningPlugin::preTestAction(UtestShell& /*test*/, TestResult& result) |
Rohit Grover |
1:4769360130ed | 438 | { |
Rohit Grover |
1:4769360130ed | 439 | memLeakDetector_->startChecking(); |
Rohit Grover |
1:4769360130ed | 440 | failureCount_ = result.getFailureCount(); |
Rohit Grover |
1:4769360130ed | 441 | } |
Rohit Grover |
1:4769360130ed | 442 | |
Rohit Grover |
1:4769360130ed | 443 | void MemoryLeakWarningPlugin::postTestAction(UtestShell& test, TestResult& result) |
Rohit Grover |
1:4769360130ed | 444 | { |
Rohit Grover |
1:4769360130ed | 445 | memLeakDetector_->stopChecking(); |
Rohit Grover |
1:4769360130ed | 446 | int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_checking); |
Rohit Grover |
1:4769360130ed | 447 | |
Rohit Grover |
1:4769360130ed | 448 | if (!ignoreAllWarnings_ && expectedLeaks_ != leaks && failureCount_ == result.getFailureCount()) { |
Rohit Grover |
1:4769360130ed | 449 | TestFailure f(&test, memLeakDetector_->report(mem_leak_period_checking)); |
Rohit Grover |
1:4769360130ed | 450 | result.addFailure(f); |
Rohit Grover |
1:4769360130ed | 451 | } |
Rohit Grover |
1:4769360130ed | 452 | memLeakDetector_->markCheckingPeriodLeaksAsNonCheckingPeriod(); |
Rohit Grover |
1:4769360130ed | 453 | ignoreAllWarnings_ = false; |
Rohit Grover |
1:4769360130ed | 454 | expectedLeaks_ = 0; |
Rohit Grover |
1:4769360130ed | 455 | } |
Rohit Grover |
1:4769360130ed | 456 | |
Rohit Grover |
1:4769360130ed | 457 | const char* MemoryLeakWarningPlugin::FinalReport(int toBeDeletedLeaks) |
Rohit Grover |
1:4769360130ed | 458 | { |
Rohit Grover |
1:4769360130ed | 459 | int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_enabled); |
Rohit Grover |
1:4769360130ed | 460 | if (leaks != toBeDeletedLeaks) return memLeakDetector_->report(mem_leak_period_enabled); |
Rohit Grover |
1:4769360130ed | 461 | return ""; |
Rohit Grover |
1:4769360130ed | 462 | } |
Rohit Grover |
1:4769360130ed | 463 | |
Rohit Grover |
1:4769360130ed | 464 |