fork
Fork of cpputest by
Embed:
(wiki syntax)
Show/hide line numbers
MemoryLeakDetector.h
00001 /* 00002 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of the <organization> nor the 00013 * names of its contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY 00017 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00022 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00023 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00025 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #ifndef D_MemoryLeakDetector_h 00029 #define D_MemoryLeakDetector_h 00030 00031 enum MemLeakPeriod 00032 { 00033 mem_leak_period_all, 00034 mem_leak_period_disabled, 00035 mem_leak_period_enabled, 00036 mem_leak_period_checking 00037 }; 00038 00039 class TestMemoryAllocator; 00040 00041 class MemoryLeakFailure 00042 { 00043 public: 00044 virtual ~MemoryLeakFailure() 00045 { 00046 } 00047 00048 virtual void fail(char* fail_string)=0; 00049 }; 00050 00051 struct SimpleStringBuffer 00052 { 00053 enum 00054 { 00055 SIMPLE_STRING_BUFFER_LEN = 4096 00056 }; 00057 00058 SimpleStringBuffer(); 00059 void clear(); 00060 void add(const char* format, ...) __check_format__(printf, 2, 3); 00061 char* toString(); 00062 00063 void setWriteLimit(size_t write_limit); 00064 void resetWriteLimit(); 00065 bool reachedItsCapacity(); 00066 private: 00067 char buffer_[SIMPLE_STRING_BUFFER_LEN]; 00068 size_t positions_filled_; 00069 size_t write_limit_; 00070 }; 00071 00072 struct MemoryLeakDetectorNode; 00073 00074 class MemoryLeakOutputStringBuffer 00075 { 00076 public: 00077 MemoryLeakOutputStringBuffer(); 00078 00079 void clear(); 00080 00081 void startMemoryLeakReporting(); 00082 void stopMemoryLeakReporting(); 00083 00084 void reportMemoryLeak(MemoryLeakDetectorNode* leak); 00085 00086 void reportDeallocateNonAllocatedMemoryFailure(const char* freeFile, int freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); 00087 void reportMemoryCorruptionFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); 00088 void reportAllocationDeallocationMismatchFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); 00089 char* toString(); 00090 00091 private: 00092 void addAllocationLocation(const char* allocationFile, int allocationLineNumber, size_t allocationSize, TestMemoryAllocator* allocator); 00093 void addDeallocationLocation(const char* freeFile, int freeLineNumber, TestMemoryAllocator* allocator); 00094 00095 void addMemoryLeakHeader(); 00096 void addMemoryLeakFooter(int totalAmountOfLeaks); 00097 void addWarningForUsingMalloc(); 00098 void addNoMemoryLeaksMessage(); 00099 void addErrorMessageForTooMuchLeaks(); 00100 00101 private: 00102 00103 int total_leaks_; 00104 bool giveWarningOnUsingMalloc_; 00105 00106 void reportFailure(const char* message, const char* allocFile, 00107 int allocLine, size_t allocSize, 00108 TestMemoryAllocator* allocAllocator, const char* freeFile, 00109 int freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); 00110 00111 SimpleStringBuffer outputBuffer_; 00112 }; 00113 00114 struct MemoryLeakDetectorNode 00115 { 00116 MemoryLeakDetectorNode() : 00117 size_(0), number_(0), memory_(0), file_(0), line_(0), allocator_(0), period_(mem_leak_period_enabled), next_(0) 00118 { 00119 } 00120 00121 void init(char* memory, unsigned number, size_t size, TestMemoryAllocator* allocator, MemLeakPeriod period, const char* file, int line); 00122 00123 size_t size_; 00124 unsigned number_; 00125 char* memory_; 00126 const char* file_; 00127 int line_; 00128 TestMemoryAllocator* allocator_; 00129 MemLeakPeriod period_; 00130 00131 private: 00132 friend struct MemoryLeakDetectorList; 00133 MemoryLeakDetectorNode* next_; 00134 }; 00135 00136 struct MemoryLeakDetectorList 00137 { 00138 MemoryLeakDetectorList() : 00139 head_(0) 00140 {} 00141 00142 void addNewNode(MemoryLeakDetectorNode* node); 00143 MemoryLeakDetectorNode* retrieveNode(char* memory); 00144 MemoryLeakDetectorNode* removeNode(char* memory); 00145 00146 MemoryLeakDetectorNode* getFirstLeak(MemLeakPeriod period); 00147 MemoryLeakDetectorNode* getNextLeak(MemoryLeakDetectorNode* node, 00148 MemLeakPeriod period); 00149 MemoryLeakDetectorNode* getLeakFrom(MemoryLeakDetectorNode* node, 00150 MemLeakPeriod period); 00151 00152 int getTotalLeaks(MemLeakPeriod period); 00153 bool hasLeaks(MemLeakPeriod period); 00154 void clearAllAccounting(MemLeakPeriod period); 00155 00156 bool isInPeriod(MemoryLeakDetectorNode* node, MemLeakPeriod period); 00157 00158 private: 00159 MemoryLeakDetectorNode* head_; 00160 }; 00161 00162 struct MemoryLeakDetectorTable 00163 { 00164 void clearAllAccounting(MemLeakPeriod period); 00165 00166 void addNewNode(MemoryLeakDetectorNode* node); 00167 MemoryLeakDetectorNode* retrieveNode(char* memory); 00168 MemoryLeakDetectorNode* removeNode(char* memory); 00169 00170 bool hasLeaks(MemLeakPeriod period); 00171 int getTotalLeaks(MemLeakPeriod period); 00172 00173 MemoryLeakDetectorNode* getFirstLeak(MemLeakPeriod period); 00174 MemoryLeakDetectorNode* getNextLeak(MemoryLeakDetectorNode* leak, 00175 MemLeakPeriod period); 00176 00177 private: 00178 unsigned long hash(char* memory); 00179 00180 enum 00181 { 00182 hash_prime = MEMORY_LEAK_HASH_TABLE_SIZE 00183 }; 00184 MemoryLeakDetectorList table_[hash_prime]; 00185 }; 00186 00187 class MemoryLeakDetector 00188 { 00189 public: 00190 MemoryLeakDetector(MemoryLeakFailure* reporter); 00191 virtual ~MemoryLeakDetector() 00192 { 00193 } 00194 00195 void enable(); 00196 void disable(); 00197 00198 void disableAllocationTypeChecking(); 00199 void enableAllocationTypeChecking(); 00200 00201 void startChecking(); 00202 void stopChecking(); 00203 00204 const char* report(MemLeakPeriod period); 00205 void markCheckingPeriodLeaksAsNonCheckingPeriod(); 00206 int totalMemoryLeaks(MemLeakPeriod period); 00207 void clearAllAccounting(MemLeakPeriod period); 00208 00209 char* allocMemory(TestMemoryAllocator* allocator, size_t size, bool allocatNodesSeperately = false); 00210 char* allocMemory(TestMemoryAllocator* allocator, size_t size, 00211 const char* file, int line, bool allocatNodesSeperately = false); 00212 void deallocMemory(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately = false); 00213 void deallocMemory(TestMemoryAllocator* allocator, void* memory, const char* file, int line, bool allocatNodesSeperately = false); 00214 char* reallocMemory(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately = false); 00215 00216 void invalidateMemory(char* memory); 00217 void removeMemoryLeakInformationWithoutCheckingOrDeallocatingTheMemoryButDeallocatingTheAccountInformation(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately); 00218 enum 00219 { 00220 memory_corruption_buffer_size = 3 00221 }; 00222 00223 unsigned getCurrentAllocationNumber(); 00224 private: 00225 MemoryLeakFailure* reporter_; 00226 MemLeakPeriod current_period_; 00227 MemoryLeakOutputStringBuffer outputBuffer_; 00228 MemoryLeakDetectorTable memoryTable_; 00229 bool doAllocationTypeChecking_; 00230 unsigned allocationSequenceNumber_; 00231 00232 char* allocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately); 00233 char* reallocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately); 00234 MemoryLeakDetectorNode* createMemoryLeakAccountingInformation(TestMemoryAllocator* allocator, size_t size, char* memory, bool allocatNodesSeperately); 00235 00236 00237 bool validMemoryCorruptionInformation(char* memory); 00238 bool matchingAllocation(TestMemoryAllocator *alloc_allocator, TestMemoryAllocator *free_allocator); 00239 00240 void storeLeakInformation(MemoryLeakDetectorNode * node, char *new_memory, size_t size, TestMemoryAllocator *allocator, const char *file, int line); 00241 void ConstructMemoryLeakReport(MemLeakPeriod period); 00242 00243 size_t sizeOfMemoryWithCorruptionInfo(size_t size); 00244 MemoryLeakDetectorNode* getNodeFromMemoryPointer(char* memory, size_t size); 00245 00246 char* reallocateMemoryAndLeakInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately); 00247 00248 void addMemoryCorruptionInformation(char* memory); 00249 void checkForCorruption(MemoryLeakDetectorNode* node, const char* file, int line, TestMemoryAllocator* allocator, bool allocateNodesSeperately); 00250 }; 00251 00252 #endif
Generated on Tue Jul 12 2022 21:37:56 by 1.7.2