CppUTest
MemoryLeakDetector.h
1 /*
2  * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the <organization> nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef D_MemoryLeakDetector_h
29 #define D_MemoryLeakDetector_h
30 
31 #define MEM_LEAK_NONE "No memory leaks were detected."
32 #define MEM_LEAK_HEADER "Memory leak(s) found.\n"
33 #define MEM_LEAK_LEAK "Alloc num (%u) Leak size: %d Allocated at: %s and line: %d. Type: \"%s\"\n\t Memory: <%p> Content: \"%.15s\"\n"
34 #define MEM_LEAK_TOO_MUCH "\netc etc etc etc. !!!! Too much memory leaks to report. Bailing out\n"
35 #define MEM_LEAK_FOOTER "Total number of leaks: "
36 #define MEM_LEAK_ADDITION_MALLOC_WARNING "NOTE:\n" \
37  "\tMemory leak reports about malloc and free can be caused by allocating using the cpputest version of malloc,\n" \
38  "\tbut deallocate using the standard free.\n" \
39  "\tIf this is the case, check whether your malloc/free replacements are working (#define malloc cpputest_malloc etc).\n"
40 
41 #define MEM_LEAK_NORMAL_FOOTER_SIZE (sizeof(MEM_LEAK_FOOTER) + 10 + sizeof(MEM_LEAK_TOO_MUCH)) /* the number of leaks */
42 #define MEM_LEAK_NORMAL_MALLOC_FOOTER_SIZE (MEM_LEAK_NORMAL_FOOTER_SIZE + sizeof(MEM_LEAK_ADDITION_MALLOC_WARNING))
43 
44 
45 #define MEM_LEAK_ALLOC_DEALLOC_MISMATCH "Allocation/deallocation type mismatch\n"
46 #define MEM_LEAK_MEMORY_CORRUPTION "Memory corruption (written out of bounds?)\n"
47 #define MEM_LEAK_ALLOC_LOCATION " allocated at file: %s line: %d size: %d type: %s\n"
48 #define MEM_LEAK_DEALLOC_LOCATION " deallocated at file: %s line: %d type: %s\n"
49 #define MEM_LEAK_DEALLOC_NON_ALLOCATED "Deallocating non-allocated memory\n"
50 
51 enum MemLeakPeriod
52 {
53  mem_leak_period_all,
54  mem_leak_period_disabled,
55  mem_leak_period_enabled,
56  mem_leak_period_checking
57 };
58 
60 
62 {
63 public:
64  virtual ~MemoryLeakFailure()
65  {
66  }
67 
68  virtual void fail(char* fail_string)=0;
69 };
70 
72 {
73  enum
74  {
75  SIMPLE_STRING_BUFFER_LEN = 4096
76  };
77 
79  void clear();
80  void add(const char* format, ...);
81  char* toString();
82 
83  void setWriteLimit(size_t write_limit);
84  void resetWriteLimit();
85  bool reachedItsCapacity();
86 private:
87  char buffer_[SIMPLE_STRING_BUFFER_LEN];
88  size_t positions_filled_;
89  size_t write_limit_;
90 };
91 
93 {
95  size_(0), next_(0)
96  {
97  }
98 
99  void init(char* memory, unsigned number, size_t size, TestMemoryAllocator* allocator, MemLeakPeriod period, const char* file, int line);
100 
101  size_t size_;
102  unsigned number_;
103  char* memory_;
104  const char* file_;
105  int line_;
106  TestMemoryAllocator* allocator_;
107  MemLeakPeriod period_;
108 
109 private:
110  friend struct MemoryLeakDetectorList;
111  MemoryLeakDetectorNode* next_;
112 };
113 
115 {
117  head_(0)
118  {}
119 
120  void addNewNode(MemoryLeakDetectorNode* node);
121  MemoryLeakDetectorNode* retrieveNode(char* memory);
122  MemoryLeakDetectorNode* removeNode(char* memory);
123 
124  MemoryLeakDetectorNode* getFirstLeak(MemLeakPeriod period);
126  MemLeakPeriod period);
128  MemLeakPeriod period);
129 
130  int getTotalLeaks(MemLeakPeriod period);
131  bool hasLeaks(MemLeakPeriod period);
132  void clearAllAccounting(MemLeakPeriod period);
133 
134  bool isInPeriod(MemoryLeakDetectorNode* node, MemLeakPeriod period);
135 
136 private:
137  MemoryLeakDetectorNode* head_;
138 };
139 
141 {
142  void clearAllAccounting(MemLeakPeriod period);
143 
144  void addNewNode(MemoryLeakDetectorNode* node);
145  MemoryLeakDetectorNode* retrieveNode(char* memory);
146  MemoryLeakDetectorNode* removeNode(char* memory);
147 
148  bool hasLeaks(MemLeakPeriod period);
149  int getTotalLeaks(MemLeakPeriod period);
150 
151  MemoryLeakDetectorNode* getFirstLeak(MemLeakPeriod period);
153  MemLeakPeriod period);
154 
155 private:
156  unsigned long hash(char* memory);
157 
158  enum
159  {
160  hash_prime = MEMORY_LEAK_HASH_TABLE_SIZE
161  };
162  MemoryLeakDetectorList table_[hash_prime];
163 };
164 
166 {
167 public:
169  virtual ~MemoryLeakDetector()
170  {
171  }
172 
173  void enable();
174  void disable();
175 
176  void disableAllocationTypeChecking();
177  void enableAllocationTypeChecking();
178 
179  void startChecking();
180  void stopChecking();
181 
182  const char* report(MemLeakPeriod period);
183  void markCheckingPeriodLeaksAsNonCheckingPeriod();
184  int totalMemoryLeaks(MemLeakPeriod period);
185  void clearAllAccounting(MemLeakPeriod period);
186 
187  char* allocMemory(TestMemoryAllocator* allocator, size_t size, bool allocatNodesSeperately = false);
188  char* allocMemory(TestMemoryAllocator* allocator, size_t size,
189  const char* file, int line, bool allocatNodesSeperately = false);
190  void deallocMemory(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately = false);
191  void deallocMemory(TestMemoryAllocator* allocator, void* memory, const char* file, int line, bool allocatNodesSeperately = false);
192  char* reallocMemory(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately = false);
193 
194  void invalidateMemory(char* memory);
195  void removeMemoryLeakInformationWithoutCheckingOrDeallocating(void* memory);
196  enum
197  {
198  memory_corruption_buffer_size = 3
199  };
200 
201  unsigned getCurrentAllocationNumber();
202 private:
203  MemoryLeakFailure* reporter_;
204  MemLeakPeriod current_period_;
205  SimpleStringBuffer output_buffer_;
206  MemoryLeakDetectorTable memoryTable_;
207  bool doAllocationTypeChecking_;
208  unsigned allocationSequenceNumber_;
209 
210  bool validMemoryCorruptionInformation(char* memory);
211  bool matchingAllocation(TestMemoryAllocator *alloc_allocator, TestMemoryAllocator *free_allocator);
212 
213  void storeLeakInformation(MemoryLeakDetectorNode * node, char *new_memory, size_t size, TestMemoryAllocator *allocator, const char *file, int line);
214  void ConstructMemoryLeakReport(MemLeakPeriod period);
215  void reportFailure(const char* message, const char* allocFile,
216  int allocLine, size_t allocSize,
217  TestMemoryAllocator* allocAllocator, const char* freeFile,
218  int freeLine, TestMemoryAllocator* freeAllocator);
219 
220  size_t sizeOfMemoryWithCorruptionInfo(size_t size);
221  MemoryLeakDetectorNode* getNodeFromMemoryPointer(char* memory, size_t size);
222 
223  char* reallocateMemoryAndLeakInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line);
224 
225  void addMemoryCorruptionInformation(char* memory);
226  void checkForCorruption(MemoryLeakDetectorNode* node, const char* file, int line, TestMemoryAllocator* allocator, bool allocateNodesSeperately);
227 };
228 
229 #endif
Definition: MemoryLeakDetector.h:140
Definition: MemoryLeakDetector.h:71
Definition: MemoryLeakDetector.h:165
Definition: MemoryLeakDetector.h:92
Definition: MemoryLeakDetector.h:114
Definition: MemoryLeakDetector.h:61
Definition: TestMemoryAllocator.h:49