fork

Fork of cpputest by Rohit Grover

Committer:
Kojto
Date:
Wed May 13 13:20:35 2015 +0000
Revision:
3:9e8c8907d9ee
Parent:
1:4769360130ed
Rename console to mbed_cpputest_console (as in mbed testrunner)

Who changed what in which revision?

UserRevisionLine numberNew 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 #include "CppUTest/TestHarness.h"
Rohit Grover 1:4769360130ed 28 #include "CppUTest/MemoryLeakDetector.h"
Rohit Grover 1:4769360130ed 29 #include "CppUTest/TestMemoryAllocator.h"
Rohit Grover 1:4769360130ed 30 #include "CppUTest/PlatformSpecificFunctions.h"
Rohit Grover 1:4769360130ed 31
Rohit Grover 1:4769360130ed 32 #define UNKNOWN ((char*)("<unknown>"))
Rohit Grover 1:4769360130ed 33
Rohit Grover 1:4769360130ed 34 SimpleStringBuffer::SimpleStringBuffer() :
Rohit Grover 1:4769360130ed 35 positions_filled_(0), write_limit_(SIMPLE_STRING_BUFFER_LEN-1)
Rohit Grover 1:4769360130ed 36 {
Rohit Grover 1:4769360130ed 37 }
Rohit Grover 1:4769360130ed 38
Rohit Grover 1:4769360130ed 39 void SimpleStringBuffer::clear()
Rohit Grover 1:4769360130ed 40 {
Rohit Grover 1:4769360130ed 41 positions_filled_ = 0;
Rohit Grover 1:4769360130ed 42 buffer_[0] = '\0';
Rohit Grover 1:4769360130ed 43 }
Rohit Grover 1:4769360130ed 44
Rohit Grover 1:4769360130ed 45 void SimpleStringBuffer::add(const char* format, ...)
Rohit Grover 1:4769360130ed 46 {
Rohit Grover 1:4769360130ed 47 int count = 0;
Rohit Grover 1:4769360130ed 48 size_t positions_left = write_limit_ - positions_filled_;
Rohit Grover 1:4769360130ed 49 if (positions_left <= 0) return;
Rohit Grover 1:4769360130ed 50
Rohit Grover 1:4769360130ed 51 va_list arguments;
Rohit Grover 1:4769360130ed 52 va_start(arguments, format);
Rohit Grover 1:4769360130ed 53 count = PlatformSpecificVSNprintf(buffer_ + positions_filled_, positions_left+1, format, arguments);
Rohit Grover 1:4769360130ed 54 if (count > 0) positions_filled_ += (size_t) count;
Rohit Grover 1:4769360130ed 55 if (positions_filled_ > write_limit_) positions_filled_ = write_limit_;
Rohit Grover 1:4769360130ed 56 va_end(arguments);
Rohit Grover 1:4769360130ed 57 }
Rohit Grover 1:4769360130ed 58
Rohit Grover 1:4769360130ed 59 char* SimpleStringBuffer::toString()
Rohit Grover 1:4769360130ed 60 {
Rohit Grover 1:4769360130ed 61 return buffer_;
Rohit Grover 1:4769360130ed 62 }
Rohit Grover 1:4769360130ed 63
Rohit Grover 1:4769360130ed 64 void SimpleStringBuffer::setWriteLimit(size_t write_limit)
Rohit Grover 1:4769360130ed 65 {
Rohit Grover 1:4769360130ed 66 write_limit_ = write_limit;
Rohit Grover 1:4769360130ed 67 if (write_limit_ > SIMPLE_STRING_BUFFER_LEN-1)
Rohit Grover 1:4769360130ed 68 write_limit_ = SIMPLE_STRING_BUFFER_LEN-1;
Rohit Grover 1:4769360130ed 69 }
Rohit Grover 1:4769360130ed 70 void SimpleStringBuffer::resetWriteLimit()
Rohit Grover 1:4769360130ed 71 {
Rohit Grover 1:4769360130ed 72 write_limit_ = SIMPLE_STRING_BUFFER_LEN-1;
Rohit Grover 1:4769360130ed 73 }
Rohit Grover 1:4769360130ed 74
Rohit Grover 1:4769360130ed 75 bool SimpleStringBuffer::reachedItsCapacity()
Rohit Grover 1:4769360130ed 76 {
Rohit Grover 1:4769360130ed 77 return positions_filled_ >= write_limit_;
Rohit Grover 1:4769360130ed 78 }
Rohit Grover 1:4769360130ed 79
Rohit Grover 1:4769360130ed 80 ////////////////////////
Rohit Grover 1:4769360130ed 81
Rohit Grover 1:4769360130ed 82 #define MEM_LEAK_TOO_MUCH "\netc etc etc etc. !!!! Too much memory leaks to report. Bailing out\n"
Rohit Grover 1:4769360130ed 83 #define MEM_LEAK_FOOTER "Total number of leaks: "
Rohit Grover 1:4769360130ed 84 #define MEM_LEAK_ADDITION_MALLOC_WARNING "NOTE:\n" \
Rohit Grover 1:4769360130ed 85 "\tMemory leak reports about malloc and free can be caused by allocating using the cpputest version of malloc,\n" \
Rohit Grover 1:4769360130ed 86 "\tbut deallocate using the standard free.\n" \
Rohit Grover 1:4769360130ed 87 "\tIf this is the case, check whether your malloc/free replacements are working (#define malloc cpputest_malloc etc).\n"
Rohit Grover 1:4769360130ed 88
Rohit Grover 1:4769360130ed 89 MemoryLeakOutputStringBuffer::MemoryLeakOutputStringBuffer()
Rohit Grover 1:4769360130ed 90 : total_leaks_(0), giveWarningOnUsingMalloc_(false)
Rohit Grover 1:4769360130ed 91 {
Rohit Grover 1:4769360130ed 92 }
Rohit Grover 1:4769360130ed 93
Rohit Grover 1:4769360130ed 94 void MemoryLeakOutputStringBuffer::addAllocationLocation(const char* allocationFile, int allocationLineNumber, size_t allocationSize, TestMemoryAllocator* allocator)
Rohit Grover 1:4769360130ed 95 {
Rohit Grover 1:4769360130ed 96 outputBuffer_.add(" allocated at file: %s line: %d size: %lu type: %s\n", allocationFile, allocationLineNumber, (unsigned long) allocationSize, allocator->alloc_name());
Rohit Grover 1:4769360130ed 97 }
Rohit Grover 1:4769360130ed 98
Rohit Grover 1:4769360130ed 99 void MemoryLeakOutputStringBuffer::addDeallocationLocation(const char* freeFile, int freeLineNumber, TestMemoryAllocator* allocator)
Rohit Grover 1:4769360130ed 100 {
Rohit Grover 1:4769360130ed 101 outputBuffer_.add(" deallocated at file: %s line: %d type: %s\n", freeFile, freeLineNumber, allocator->free_name());
Rohit Grover 1:4769360130ed 102 }
Rohit Grover 1:4769360130ed 103
Rohit Grover 1:4769360130ed 104 void MemoryLeakOutputStringBuffer::addNoMemoryLeaksMessage()
Rohit Grover 1:4769360130ed 105 {
Rohit Grover 1:4769360130ed 106 outputBuffer_.add("No memory leaks were detected.");
Rohit Grover 1:4769360130ed 107 }
Rohit Grover 1:4769360130ed 108
Rohit Grover 1:4769360130ed 109 void MemoryLeakOutputStringBuffer::startMemoryLeakReporting()
Rohit Grover 1:4769360130ed 110 {
Rohit Grover 1:4769360130ed 111 giveWarningOnUsingMalloc_ = false;
Rohit Grover 1:4769360130ed 112 total_leaks_ = 0;
Rohit Grover 1:4769360130ed 113
Rohit Grover 1:4769360130ed 114 size_t memory_leak_normal_footer_size = sizeof(MEM_LEAK_FOOTER) + 10 + sizeof(MEM_LEAK_TOO_MUCH); /* the number of leaks */
Rohit Grover 1:4769360130ed 115 size_t memory_leak_foot_size_with_malloc_warning = memory_leak_normal_footer_size + sizeof(MEM_LEAK_ADDITION_MALLOC_WARNING);
Rohit Grover 1:4769360130ed 116
Rohit Grover 1:4769360130ed 117 outputBuffer_.setWriteLimit(SimpleStringBuffer::SIMPLE_STRING_BUFFER_LEN - memory_leak_foot_size_with_malloc_warning);
Rohit Grover 1:4769360130ed 118 }
Rohit Grover 1:4769360130ed 119
Rohit Grover 1:4769360130ed 120 void MemoryLeakOutputStringBuffer::reportMemoryLeak(MemoryLeakDetectorNode* leak)
Rohit Grover 1:4769360130ed 121 {
Rohit Grover 1:4769360130ed 122 if (total_leaks_ == 0) {
Rohit Grover 1:4769360130ed 123 addMemoryLeakHeader();
Rohit Grover 1:4769360130ed 124 }
Rohit Grover 1:4769360130ed 125
Rohit Grover 1:4769360130ed 126 total_leaks_++;
Rohit Grover 1:4769360130ed 127 outputBuffer_.add("Alloc num (%u) Leak size: %lu Allocated at: %s and line: %d. Type: \"%s\"\n\t Memory: <%p> Content: \"%.15s\"\n",
Rohit Grover 1:4769360130ed 128 leak->number_, (unsigned long) leak->size_, leak->file_, leak->line_, leak->allocator_->alloc_name(), leak->memory_, leak->memory_);
Rohit Grover 1:4769360130ed 129
Rohit Grover 1:4769360130ed 130 if (PlatformSpecificStrCmp(leak->allocator_->alloc_name(), "malloc") == 0)
Rohit Grover 1:4769360130ed 131 giveWarningOnUsingMalloc_ = true;
Rohit Grover 1:4769360130ed 132 }
Rohit Grover 1:4769360130ed 133
Rohit Grover 1:4769360130ed 134 void MemoryLeakOutputStringBuffer::stopMemoryLeakReporting()
Rohit Grover 1:4769360130ed 135 {
Rohit Grover 1:4769360130ed 136 if (total_leaks_ == 0) {
Rohit Grover 1:4769360130ed 137 addNoMemoryLeaksMessage();
Rohit Grover 1:4769360130ed 138 return;
Rohit Grover 1:4769360130ed 139 }
Rohit Grover 1:4769360130ed 140
Rohit Grover 1:4769360130ed 141 bool buffer_reached_its_capacity = outputBuffer_.reachedItsCapacity();
Rohit Grover 1:4769360130ed 142 outputBuffer_.resetWriteLimit();
Rohit Grover 1:4769360130ed 143
Rohit Grover 1:4769360130ed 144 if (buffer_reached_its_capacity)
Rohit Grover 1:4769360130ed 145 addErrorMessageForTooMuchLeaks();
Rohit Grover 1:4769360130ed 146
Rohit Grover 1:4769360130ed 147 addMemoryLeakFooter(total_leaks_);
Rohit Grover 1:4769360130ed 148
Rohit Grover 1:4769360130ed 149 if (giveWarningOnUsingMalloc_)
Rohit Grover 1:4769360130ed 150 addWarningForUsingMalloc();
Rohit Grover 1:4769360130ed 151
Rohit Grover 1:4769360130ed 152 }
Rohit Grover 1:4769360130ed 153
Rohit Grover 1:4769360130ed 154 void MemoryLeakOutputStringBuffer::addMemoryLeakHeader()
Rohit Grover 1:4769360130ed 155 {
Rohit Grover 1:4769360130ed 156 outputBuffer_.add("Memory leak(s) found.\n");
Rohit Grover 1:4769360130ed 157 }
Rohit Grover 1:4769360130ed 158
Rohit Grover 1:4769360130ed 159 void MemoryLeakOutputStringBuffer::addErrorMessageForTooMuchLeaks()
Rohit Grover 1:4769360130ed 160 {
Rohit Grover 1:4769360130ed 161 outputBuffer_.add(MEM_LEAK_TOO_MUCH);
Rohit Grover 1:4769360130ed 162 }
Rohit Grover 1:4769360130ed 163
Rohit Grover 1:4769360130ed 164 void MemoryLeakOutputStringBuffer::addMemoryLeakFooter(int amountOfLeaks)
Rohit Grover 1:4769360130ed 165 {
Rohit Grover 1:4769360130ed 166 outputBuffer_.add("%s %d\n", MEM_LEAK_FOOTER, amountOfLeaks);
Rohit Grover 1:4769360130ed 167 }
Rohit Grover 1:4769360130ed 168
Rohit Grover 1:4769360130ed 169 void MemoryLeakOutputStringBuffer::addWarningForUsingMalloc()
Rohit Grover 1:4769360130ed 170 {
Rohit Grover 1:4769360130ed 171 outputBuffer_.add(MEM_LEAK_ADDITION_MALLOC_WARNING);
Rohit Grover 1:4769360130ed 172 }
Rohit Grover 1:4769360130ed 173
Rohit Grover 1:4769360130ed 174 void MemoryLeakOutputStringBuffer::reportDeallocateNonAllocatedMemoryFailure(const char* freeFile, int freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
Rohit Grover 1:4769360130ed 175 {
Rohit Grover 1:4769360130ed 176 reportFailure("Deallocating non-allocated memory\n", "<unknown>", 0, 0, NullUnknownAllocator::defaultAllocator(), freeFile, freeLine, freeAllocator, reporter);
Rohit Grover 1:4769360130ed 177 }
Rohit Grover 1:4769360130ed 178
Rohit Grover 1:4769360130ed 179 void MemoryLeakOutputStringBuffer::reportAllocationDeallocationMismatchFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
Rohit Grover 1:4769360130ed 180 {
Rohit Grover 1:4769360130ed 181 reportFailure("Allocation/deallocation type mismatch\n", node->file_, node->line_, node->size_, node->allocator_, freeFile, freeLineNumber, freeAllocator, reporter);
Rohit Grover 1:4769360130ed 182 }
Rohit Grover 1:4769360130ed 183
Rohit Grover 1:4769360130ed 184 void MemoryLeakOutputStringBuffer::reportMemoryCorruptionFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
Rohit Grover 1:4769360130ed 185 {
Rohit Grover 1:4769360130ed 186 reportFailure("Memory corruption (written out of bounds?)\n", node->file_, node->line_, node->size_, node->allocator_, freeFile, freeLineNumber, freeAllocator, reporter);
Rohit Grover 1:4769360130ed 187 }
Rohit Grover 1:4769360130ed 188
Rohit Grover 1:4769360130ed 189 void MemoryLeakOutputStringBuffer::reportFailure(const char* message, const char* allocFile, int allocLine, size_t allocSize, TestMemoryAllocator* allocAllocator, const char* freeFile, int freeLine,
Rohit Grover 1:4769360130ed 190 TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
Rohit Grover 1:4769360130ed 191 {
Rohit Grover 1:4769360130ed 192 outputBuffer_.add("%s", message);
Rohit Grover 1:4769360130ed 193 addAllocationLocation(allocFile, allocLine, allocSize, allocAllocator);
Rohit Grover 1:4769360130ed 194 addDeallocationLocation(freeFile, freeLine, freeAllocator);
Rohit Grover 1:4769360130ed 195 reporter->fail(toString());
Rohit Grover 1:4769360130ed 196 }
Rohit Grover 1:4769360130ed 197
Rohit Grover 1:4769360130ed 198
Rohit Grover 1:4769360130ed 199 char* MemoryLeakOutputStringBuffer::toString()
Rohit Grover 1:4769360130ed 200 {
Rohit Grover 1:4769360130ed 201 return outputBuffer_.toString();
Rohit Grover 1:4769360130ed 202 }
Rohit Grover 1:4769360130ed 203
Rohit Grover 1:4769360130ed 204 void MemoryLeakOutputStringBuffer::clear()
Rohit Grover 1:4769360130ed 205 {
Rohit Grover 1:4769360130ed 206 outputBuffer_.clear();
Rohit Grover 1:4769360130ed 207 }
Rohit Grover 1:4769360130ed 208
Rohit Grover 1:4769360130ed 209 ////////////////////////
Rohit Grover 1:4769360130ed 210
Rohit Grover 1:4769360130ed 211 void MemoryLeakDetectorNode::init(char* memory, unsigned number, size_t size, TestMemoryAllocator* allocator, MemLeakPeriod period, const char* file, int line)
Rohit Grover 1:4769360130ed 212 {
Rohit Grover 1:4769360130ed 213 number_ = number;
Rohit Grover 1:4769360130ed 214 memory_ = memory;
Rohit Grover 1:4769360130ed 215 size_ = size;
Rohit Grover 1:4769360130ed 216 allocator_ = allocator;
Rohit Grover 1:4769360130ed 217 period_ = period;
Rohit Grover 1:4769360130ed 218 file_ = file;
Rohit Grover 1:4769360130ed 219 line_ = line;
Rohit Grover 1:4769360130ed 220 }
Rohit Grover 1:4769360130ed 221
Rohit Grover 1:4769360130ed 222 ///////////////////////
Rohit Grover 1:4769360130ed 223
Rohit Grover 1:4769360130ed 224 bool MemoryLeakDetectorList::isInPeriod(MemoryLeakDetectorNode* node, MemLeakPeriod period)
Rohit Grover 1:4769360130ed 225 {
Rohit Grover 1:4769360130ed 226 return period == mem_leak_period_all || node->period_ == period || (node->period_ != mem_leak_period_disabled && period == mem_leak_period_enabled);
Rohit Grover 1:4769360130ed 227 }
Rohit Grover 1:4769360130ed 228
Rohit Grover 1:4769360130ed 229 void MemoryLeakDetectorList::clearAllAccounting(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 230 {
Rohit Grover 1:4769360130ed 231 MemoryLeakDetectorNode* cur = head_;
Rohit Grover 1:4769360130ed 232 MemoryLeakDetectorNode* prev = 0;
Rohit Grover 1:4769360130ed 233
Rohit Grover 1:4769360130ed 234 while (cur) {
Rohit Grover 1:4769360130ed 235 if (isInPeriod(cur, period)) {
Rohit Grover 1:4769360130ed 236 if (prev) {
Rohit Grover 1:4769360130ed 237 prev->next_ = cur->next_;
Rohit Grover 1:4769360130ed 238 cur = prev;
Rohit Grover 1:4769360130ed 239 }
Rohit Grover 1:4769360130ed 240 else {
Rohit Grover 1:4769360130ed 241 head_ = cur->next_;
Rohit Grover 1:4769360130ed 242 cur = head_;
Rohit Grover 1:4769360130ed 243 continue;
Rohit Grover 1:4769360130ed 244 }
Rohit Grover 1:4769360130ed 245 }
Rohit Grover 1:4769360130ed 246 prev = cur;
Rohit Grover 1:4769360130ed 247 cur = cur->next_;
Rohit Grover 1:4769360130ed 248 }
Rohit Grover 1:4769360130ed 249 }
Rohit Grover 1:4769360130ed 250
Rohit Grover 1:4769360130ed 251 void MemoryLeakDetectorList::addNewNode(MemoryLeakDetectorNode* node)
Rohit Grover 1:4769360130ed 252 {
Rohit Grover 1:4769360130ed 253 node->next_ = head_;
Rohit Grover 1:4769360130ed 254 head_ = node;
Rohit Grover 1:4769360130ed 255 }
Rohit Grover 1:4769360130ed 256
Rohit Grover 1:4769360130ed 257 MemoryLeakDetectorNode* MemoryLeakDetectorList::removeNode(char* memory)
Rohit Grover 1:4769360130ed 258 {
Rohit Grover 1:4769360130ed 259 MemoryLeakDetectorNode* cur = head_;
Rohit Grover 1:4769360130ed 260 MemoryLeakDetectorNode* prev = 0;
Rohit Grover 1:4769360130ed 261 while (cur) {
Rohit Grover 1:4769360130ed 262 if (cur->memory_ == memory) {
Rohit Grover 1:4769360130ed 263 if (prev) {
Rohit Grover 1:4769360130ed 264 prev->next_ = cur->next_;
Rohit Grover 1:4769360130ed 265 return cur;
Rohit Grover 1:4769360130ed 266 }
Rohit Grover 1:4769360130ed 267 else {
Rohit Grover 1:4769360130ed 268 head_ = cur->next_;
Rohit Grover 1:4769360130ed 269 return cur;
Rohit Grover 1:4769360130ed 270 }
Rohit Grover 1:4769360130ed 271 }
Rohit Grover 1:4769360130ed 272 prev = cur;
Rohit Grover 1:4769360130ed 273 cur = cur->next_;
Rohit Grover 1:4769360130ed 274 }
Rohit Grover 1:4769360130ed 275 return 0;
Rohit Grover 1:4769360130ed 276 }
Rohit Grover 1:4769360130ed 277
Rohit Grover 1:4769360130ed 278 MemoryLeakDetectorNode* MemoryLeakDetectorList::retrieveNode(char* memory)
Rohit Grover 1:4769360130ed 279 {
Rohit Grover 1:4769360130ed 280 MemoryLeakDetectorNode* cur = head_;
Rohit Grover 1:4769360130ed 281 while (cur) {
Rohit Grover 1:4769360130ed 282 if (cur->memory_ == memory)
Rohit Grover 1:4769360130ed 283 return cur;
Rohit Grover 1:4769360130ed 284 cur = cur->next_;
Rohit Grover 1:4769360130ed 285 }
Rohit Grover 1:4769360130ed 286 return NULL;
Rohit Grover 1:4769360130ed 287 }
Rohit Grover 1:4769360130ed 288
Rohit Grover 1:4769360130ed 289 MemoryLeakDetectorNode* MemoryLeakDetectorList::getLeakFrom(MemoryLeakDetectorNode* node, MemLeakPeriod period)
Rohit Grover 1:4769360130ed 290 {
Rohit Grover 1:4769360130ed 291 for (MemoryLeakDetectorNode* cur = node; cur; cur = cur->next_)
Rohit Grover 1:4769360130ed 292 if (isInPeriod(cur, period)) return cur;
Rohit Grover 1:4769360130ed 293 return 0;
Rohit Grover 1:4769360130ed 294 }
Rohit Grover 1:4769360130ed 295
Rohit Grover 1:4769360130ed 296 MemoryLeakDetectorNode* MemoryLeakDetectorList::getFirstLeak(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 297 {
Rohit Grover 1:4769360130ed 298 return getLeakFrom(head_, period);
Rohit Grover 1:4769360130ed 299 }
Rohit Grover 1:4769360130ed 300
Rohit Grover 1:4769360130ed 301 MemoryLeakDetectorNode* MemoryLeakDetectorList::getNextLeak(MemoryLeakDetectorNode* node, MemLeakPeriod period)
Rohit Grover 1:4769360130ed 302 {
Rohit Grover 1:4769360130ed 303 return getLeakFrom(node->next_, period);
Rohit Grover 1:4769360130ed 304 }
Rohit Grover 1:4769360130ed 305
Rohit Grover 1:4769360130ed 306 int MemoryLeakDetectorList::getTotalLeaks(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 307 {
Rohit Grover 1:4769360130ed 308 int total_leaks = 0;
Rohit Grover 1:4769360130ed 309 for (MemoryLeakDetectorNode* node = head_; node; node = node->next_) {
Rohit Grover 1:4769360130ed 310 if (isInPeriod(node, period)) total_leaks++;
Rohit Grover 1:4769360130ed 311 }
Rohit Grover 1:4769360130ed 312 return total_leaks;
Rohit Grover 1:4769360130ed 313 }
Rohit Grover 1:4769360130ed 314
Rohit Grover 1:4769360130ed 315 bool MemoryLeakDetectorList::hasLeaks(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 316 {
Rohit Grover 1:4769360130ed 317 for (MemoryLeakDetectorNode* node = head_; node; node = node->next_)
Rohit Grover 1:4769360130ed 318 if (isInPeriod(node, period)) return true;
Rohit Grover 1:4769360130ed 319 return false;
Rohit Grover 1:4769360130ed 320 }
Rohit Grover 1:4769360130ed 321
Rohit Grover 1:4769360130ed 322 /////////////////////////////////////////////////////////////
Rohit Grover 1:4769360130ed 323
Rohit Grover 1:4769360130ed 324 unsigned long MemoryLeakDetectorTable::hash(char* memory)
Rohit Grover 1:4769360130ed 325 {
Rohit Grover 1:4769360130ed 326 return (unsigned long)((size_t)memory % hash_prime);
Rohit Grover 1:4769360130ed 327 }
Rohit Grover 1:4769360130ed 328
Rohit Grover 1:4769360130ed 329 void MemoryLeakDetectorTable::clearAllAccounting(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 330 {
Rohit Grover 1:4769360130ed 331 for (int i = 0; i < hash_prime; i++)
Rohit Grover 1:4769360130ed 332 table_[i].clearAllAccounting(period);
Rohit Grover 1:4769360130ed 333 }
Rohit Grover 1:4769360130ed 334
Rohit Grover 1:4769360130ed 335 void MemoryLeakDetectorTable::addNewNode(MemoryLeakDetectorNode* node)
Rohit Grover 1:4769360130ed 336 {
Rohit Grover 1:4769360130ed 337 table_[hash(node->memory_)].addNewNode(node);
Rohit Grover 1:4769360130ed 338 }
Rohit Grover 1:4769360130ed 339
Rohit Grover 1:4769360130ed 340 MemoryLeakDetectorNode* MemoryLeakDetectorTable::removeNode(char* memory)
Rohit Grover 1:4769360130ed 341 {
Rohit Grover 1:4769360130ed 342 return table_[hash(memory)].removeNode(memory);
Rohit Grover 1:4769360130ed 343 }
Rohit Grover 1:4769360130ed 344
Rohit Grover 1:4769360130ed 345 MemoryLeakDetectorNode* MemoryLeakDetectorTable::retrieveNode(char* memory)
Rohit Grover 1:4769360130ed 346 {
Rohit Grover 1:4769360130ed 347 return table_[hash(memory)].retrieveNode(memory);
Rohit Grover 1:4769360130ed 348 }
Rohit Grover 1:4769360130ed 349
Rohit Grover 1:4769360130ed 350 bool MemoryLeakDetectorTable::hasLeaks(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 351 {
Rohit Grover 1:4769360130ed 352 for (int i = 0; i < hash_prime; i++)
Rohit Grover 1:4769360130ed 353 if (table_[i].hasLeaks(period)) return true;
Rohit Grover 1:4769360130ed 354 return false;
Rohit Grover 1:4769360130ed 355 }
Rohit Grover 1:4769360130ed 356
Rohit Grover 1:4769360130ed 357 int MemoryLeakDetectorTable::getTotalLeaks(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 358 {
Rohit Grover 1:4769360130ed 359 int total_leaks = 0;
Rohit Grover 1:4769360130ed 360 for (int i = 0; i < hash_prime; i++)
Rohit Grover 1:4769360130ed 361 total_leaks += table_[i].getTotalLeaks(period);
Rohit Grover 1:4769360130ed 362 return total_leaks;
Rohit Grover 1:4769360130ed 363 }
Rohit Grover 1:4769360130ed 364
Rohit Grover 1:4769360130ed 365 MemoryLeakDetectorNode* MemoryLeakDetectorTable::getFirstLeak(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 366 {
Rohit Grover 1:4769360130ed 367 for (int i = 0; i < hash_prime; i++) {
Rohit Grover 1:4769360130ed 368 MemoryLeakDetectorNode* node = table_[i].getFirstLeak(period);
Rohit Grover 1:4769360130ed 369 if (node) return node;
Rohit Grover 1:4769360130ed 370 }
Rohit Grover 1:4769360130ed 371 return 0;
Rohit Grover 1:4769360130ed 372 }
Rohit Grover 1:4769360130ed 373
Rohit Grover 1:4769360130ed 374 MemoryLeakDetectorNode* MemoryLeakDetectorTable::getNextLeak(MemoryLeakDetectorNode* leak, MemLeakPeriod period)
Rohit Grover 1:4769360130ed 375 {
Rohit Grover 1:4769360130ed 376 unsigned long i = hash(leak->memory_);
Rohit Grover 1:4769360130ed 377 MemoryLeakDetectorNode* node = table_[i].getNextLeak(leak, period);
Rohit Grover 1:4769360130ed 378 if (node) return node;
Rohit Grover 1:4769360130ed 379
Rohit Grover 1:4769360130ed 380 for (++i; i < hash_prime; i++) {
Rohit Grover 1:4769360130ed 381 node = table_[i].getFirstLeak(period);
Rohit Grover 1:4769360130ed 382 if (node) return node;
Rohit Grover 1:4769360130ed 383 }
Rohit Grover 1:4769360130ed 384 return 0;
Rohit Grover 1:4769360130ed 385 }
Rohit Grover 1:4769360130ed 386
Rohit Grover 1:4769360130ed 387 /////////////////////////////////////////////////////////////
Rohit Grover 1:4769360130ed 388
Rohit Grover 1:4769360130ed 389 MemoryLeakDetector::MemoryLeakDetector(MemoryLeakFailure* reporter)
Rohit Grover 1:4769360130ed 390 {
Rohit Grover 1:4769360130ed 391 doAllocationTypeChecking_ = true;
Rohit Grover 1:4769360130ed 392 allocationSequenceNumber_ = 1;
Rohit Grover 1:4769360130ed 393 current_period_ = mem_leak_period_disabled;
Rohit Grover 1:4769360130ed 394 reporter_ = reporter;
Rohit Grover 1:4769360130ed 395 outputBuffer_ = MemoryLeakOutputStringBuffer();
Rohit Grover 1:4769360130ed 396 memoryTable_ = MemoryLeakDetectorTable();
Rohit Grover 1:4769360130ed 397 }
Rohit Grover 1:4769360130ed 398
Rohit Grover 1:4769360130ed 399 void MemoryLeakDetector::clearAllAccounting(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 400 {
Rohit Grover 1:4769360130ed 401 memoryTable_.clearAllAccounting(period);
Rohit Grover 1:4769360130ed 402 }
Rohit Grover 1:4769360130ed 403
Rohit Grover 1:4769360130ed 404 void MemoryLeakDetector::startChecking()
Rohit Grover 1:4769360130ed 405 {
Rohit Grover 1:4769360130ed 406 outputBuffer_.clear();
Rohit Grover 1:4769360130ed 407 current_period_ = mem_leak_period_checking;
Rohit Grover 1:4769360130ed 408 }
Rohit Grover 1:4769360130ed 409
Rohit Grover 1:4769360130ed 410 void MemoryLeakDetector::stopChecking()
Rohit Grover 1:4769360130ed 411 {
Rohit Grover 1:4769360130ed 412 current_period_ = mem_leak_period_enabled;
Rohit Grover 1:4769360130ed 413 }
Rohit Grover 1:4769360130ed 414
Rohit Grover 1:4769360130ed 415 void MemoryLeakDetector::enable()
Rohit Grover 1:4769360130ed 416 {
Rohit Grover 1:4769360130ed 417 current_period_ = mem_leak_period_enabled;
Rohit Grover 1:4769360130ed 418 }
Rohit Grover 1:4769360130ed 419
Rohit Grover 1:4769360130ed 420 void MemoryLeakDetector::disable()
Rohit Grover 1:4769360130ed 421 {
Rohit Grover 1:4769360130ed 422 current_period_ = mem_leak_period_disabled;
Rohit Grover 1:4769360130ed 423 }
Rohit Grover 1:4769360130ed 424
Rohit Grover 1:4769360130ed 425 void MemoryLeakDetector::disableAllocationTypeChecking()
Rohit Grover 1:4769360130ed 426 {
Rohit Grover 1:4769360130ed 427 doAllocationTypeChecking_ = false;
Rohit Grover 1:4769360130ed 428 }
Rohit Grover 1:4769360130ed 429
Rohit Grover 1:4769360130ed 430 void MemoryLeakDetector::enableAllocationTypeChecking()
Rohit Grover 1:4769360130ed 431 {
Rohit Grover 1:4769360130ed 432 doAllocationTypeChecking_ = true;
Rohit Grover 1:4769360130ed 433 }
Rohit Grover 1:4769360130ed 434
Rohit Grover 1:4769360130ed 435 unsigned MemoryLeakDetector::getCurrentAllocationNumber()
Rohit Grover 1:4769360130ed 436 {
Rohit Grover 1:4769360130ed 437 return allocationSequenceNumber_;
Rohit Grover 1:4769360130ed 438 }
Rohit Grover 1:4769360130ed 439
Rohit Grover 1:4769360130ed 440 static size_t calculateVoidPointerAlignedSize(size_t size)
Rohit Grover 1:4769360130ed 441 {
Rohit Grover 1:4769360130ed 442 return (sizeof(void*) - (size % sizeof(void*))) + size;
Rohit Grover 1:4769360130ed 443 }
Rohit Grover 1:4769360130ed 444
Rohit Grover 1:4769360130ed 445 size_t MemoryLeakDetector::sizeOfMemoryWithCorruptionInfo(size_t size)
Rohit Grover 1:4769360130ed 446 {
Rohit Grover 1:4769360130ed 447 return calculateVoidPointerAlignedSize(size + memory_corruption_buffer_size);
Rohit Grover 1:4769360130ed 448 }
Rohit Grover 1:4769360130ed 449
Rohit Grover 1:4769360130ed 450 MemoryLeakDetectorNode* MemoryLeakDetector::getNodeFromMemoryPointer(char* memory, size_t memory_size)
Rohit Grover 1:4769360130ed 451 {
Rohit Grover 1:4769360130ed 452 return (MemoryLeakDetectorNode*) (void*) (memory + sizeOfMemoryWithCorruptionInfo(memory_size));
Rohit Grover 1:4769360130ed 453 }
Rohit Grover 1:4769360130ed 454
Rohit Grover 1:4769360130ed 455 void MemoryLeakDetector::storeLeakInformation(MemoryLeakDetectorNode * node, char *new_memory, size_t size, TestMemoryAllocator *allocator, const char *file, int line)
Rohit Grover 1:4769360130ed 456 {
Rohit Grover 1:4769360130ed 457 node->init(new_memory, allocationSequenceNumber_++, size, allocator, current_period_, file, line);
Rohit Grover 1:4769360130ed 458 addMemoryCorruptionInformation(node->memory_ + node->size_);
Rohit Grover 1:4769360130ed 459 memoryTable_.addNewNode(node);
Rohit Grover 1:4769360130ed 460 }
Rohit Grover 1:4769360130ed 461
Rohit Grover 1:4769360130ed 462 char* MemoryLeakDetector::reallocateMemoryAndLeakInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 463 {
Rohit Grover 1:4769360130ed 464 char* new_memory = reallocateMemoryWithAccountingInformation(allocator, memory, size, file, line, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 465 if (new_memory == NULL) return NULL;
Rohit Grover 1:4769360130ed 466
Rohit Grover 1:4769360130ed 467 MemoryLeakDetectorNode *node = createMemoryLeakAccountingInformation(allocator, size, new_memory, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 468 storeLeakInformation(node, new_memory, size, allocator, file, line);
Rohit Grover 1:4769360130ed 469 return node->memory_;
Rohit Grover 1:4769360130ed 470 }
Rohit Grover 1:4769360130ed 471
Rohit Grover 1:4769360130ed 472 void MemoryLeakDetector::invalidateMemory(char* memory)
Rohit Grover 1:4769360130ed 473 {
Rohit Grover 1:4769360130ed 474 MemoryLeakDetectorNode* node = memoryTable_.retrieveNode(memory);
Rohit Grover 1:4769360130ed 475 if (node)
Rohit Grover 1:4769360130ed 476 PlatformSpecificMemset(memory, 0xCD, node->size_);
Rohit Grover 1:4769360130ed 477 }
Rohit Grover 1:4769360130ed 478
Rohit Grover 1:4769360130ed 479 void MemoryLeakDetector::addMemoryCorruptionInformation(char* memory)
Rohit Grover 1:4769360130ed 480 {
Rohit Grover 1:4769360130ed 481 memory[0] = 'B';
Rohit Grover 1:4769360130ed 482 memory[1] = 'A';
Rohit Grover 1:4769360130ed 483 memory[2] = 'S';
Rohit Grover 1:4769360130ed 484 }
Rohit Grover 1:4769360130ed 485
Rohit Grover 1:4769360130ed 486 bool MemoryLeakDetector::validMemoryCorruptionInformation(char* memory)
Rohit Grover 1:4769360130ed 487 {
Rohit Grover 1:4769360130ed 488 return memory[0] == 'B' && memory[1] == 'A' && memory[2] == 'S';
Rohit Grover 1:4769360130ed 489 }
Rohit Grover 1:4769360130ed 490
Rohit Grover 1:4769360130ed 491 bool MemoryLeakDetector::matchingAllocation(TestMemoryAllocator *alloc_allocator, TestMemoryAllocator *free_allocator)
Rohit Grover 1:4769360130ed 492 {
Rohit Grover 1:4769360130ed 493 if (alloc_allocator == free_allocator) return true;
Rohit Grover 1:4769360130ed 494 if (!doAllocationTypeChecking_) return true;
Rohit Grover 1:4769360130ed 495 return free_allocator->isOfEqualType(alloc_allocator);
Rohit Grover 1:4769360130ed 496 }
Rohit Grover 1:4769360130ed 497
Rohit Grover 1:4769360130ed 498 void MemoryLeakDetector::checkForCorruption(MemoryLeakDetectorNode* node, const char* file, int line, TestMemoryAllocator* allocator, bool allocateNodesSeperately)
Rohit Grover 1:4769360130ed 499 {
Rohit Grover 1:4769360130ed 500 if (!matchingAllocation(node->allocator_, allocator))
Rohit Grover 1:4769360130ed 501 outputBuffer_.reportAllocationDeallocationMismatchFailure(node, file, line, allocator, reporter_);
Rohit Grover 1:4769360130ed 502 else if (!validMemoryCorruptionInformation(node->memory_ + node->size_))
Rohit Grover 1:4769360130ed 503 outputBuffer_.reportMemoryCorruptionFailure(node, file, line, allocator, reporter_);
Rohit Grover 1:4769360130ed 504 else if (allocateNodesSeperately)
Rohit Grover 1:4769360130ed 505 allocator->freeMemoryLeakNode((char*) node);
Rohit Grover 1:4769360130ed 506 }
Rohit Grover 1:4769360130ed 507
Rohit Grover 1:4769360130ed 508 char* MemoryLeakDetector::allocMemory(TestMemoryAllocator* allocator, size_t size, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 509 {
Rohit Grover 1:4769360130ed 510 return allocMemory(allocator, size, UNKNOWN, 0, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 511 }
Rohit Grover 1:4769360130ed 512
Rohit Grover 1:4769360130ed 513 char* MemoryLeakDetector::allocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 514 {
Rohit Grover 1:4769360130ed 515 if (allocatNodesSeperately) return allocator->alloc_memory(sizeOfMemoryWithCorruptionInfo(size), file, line);
Rohit Grover 1:4769360130ed 516 else return allocator->alloc_memory(sizeOfMemoryWithCorruptionInfo(size) + sizeof(MemoryLeakDetectorNode), file, line);
Rohit Grover 1:4769360130ed 517 }
Rohit Grover 1:4769360130ed 518
Rohit Grover 1:4769360130ed 519 char* MemoryLeakDetector::reallocateMemoryWithAccountingInformation(TestMemoryAllocator* /*allocator*/, char* memory, size_t size, const char* /*file*/, int /*line*/, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 520 {
Rohit Grover 1:4769360130ed 521 if (allocatNodesSeperately) return (char*) PlatformSpecificRealloc(memory, sizeOfMemoryWithCorruptionInfo(size));
Rohit Grover 1:4769360130ed 522 else return (char*) PlatformSpecificRealloc(memory, sizeOfMemoryWithCorruptionInfo(size) + sizeof(MemoryLeakDetectorNode));
Rohit Grover 1:4769360130ed 523 }
Rohit Grover 1:4769360130ed 524
Rohit Grover 1:4769360130ed 525 MemoryLeakDetectorNode* MemoryLeakDetector::createMemoryLeakAccountingInformation(TestMemoryAllocator* allocator, size_t size, char* memory, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 526 {
Rohit Grover 1:4769360130ed 527 if (allocatNodesSeperately) return (MemoryLeakDetectorNode*) (void*) allocator->allocMemoryLeakNode(sizeof(MemoryLeakDetectorNode));
Rohit Grover 1:4769360130ed 528 else return getNodeFromMemoryPointer(memory, size);
Rohit Grover 1:4769360130ed 529 }
Rohit Grover 1:4769360130ed 530
Rohit Grover 1:4769360130ed 531 char* MemoryLeakDetector::allocMemory(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 532 {
Rohit Grover 1:4769360130ed 533 /* With malloc, it is harder to guarantee that the allocator free is called.
Rohit Grover 1:4769360130ed 534 * This is because operator new is overloaded via linker symbols, but malloc just via #defines.
Rohit Grover 1:4769360130ed 535 * If the same allocation is used and the wrong free is called, it will deallocate the memory leak information
Rohit Grover 1:4769360130ed 536 * without the memory leak detector ever noticing it!
Rohit Grover 1:4769360130ed 537 * So, for malloc, we'll allocate the memory separately so we can detect this and give a proper error.
Rohit Grover 1:4769360130ed 538 */
Rohit Grover 1:4769360130ed 539
Rohit Grover 1:4769360130ed 540 char* memory = allocateMemoryWithAccountingInformation(allocator, size, file, line, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 541 if (memory == NULL) return NULL;
Rohit Grover 1:4769360130ed 542 MemoryLeakDetectorNode* node = createMemoryLeakAccountingInformation(allocator, size, memory, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 543
Rohit Grover 1:4769360130ed 544 storeLeakInformation(node, memory, size, allocator, file, line);
Rohit Grover 1:4769360130ed 545 return node->memory_;
Rohit Grover 1:4769360130ed 546 }
Rohit Grover 1:4769360130ed 547
Rohit Grover 1:4769360130ed 548 void MemoryLeakDetector::removeMemoryLeakInformationWithoutCheckingOrDeallocatingTheMemoryButDeallocatingTheAccountInformation(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 549 {
Rohit Grover 1:4769360130ed 550 MemoryLeakDetectorNode* node = memoryTable_.removeNode((char*) memory);
Rohit Grover 1:4769360130ed 551 if (allocatNodesSeperately) allocator->freeMemoryLeakNode( (char*) node);
Rohit Grover 1:4769360130ed 552 }
Rohit Grover 1:4769360130ed 553
Rohit Grover 1:4769360130ed 554 void MemoryLeakDetector::deallocMemory(TestMemoryAllocator* allocator, void* memory, const char* file, int line, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 555 {
Rohit Grover 1:4769360130ed 556 if (memory == 0) return;
Rohit Grover 1:4769360130ed 557
Rohit Grover 1:4769360130ed 558 MemoryLeakDetectorNode* node = memoryTable_.removeNode((char*) memory);
Rohit Grover 1:4769360130ed 559 if (node == NULL) {
Rohit Grover 1:4769360130ed 560 outputBuffer_.reportDeallocateNonAllocatedMemoryFailure(file, line, allocator, reporter_);
Rohit Grover 1:4769360130ed 561 return;
Rohit Grover 1:4769360130ed 562 }
Rohit Grover 1:4769360130ed 563 if (!allocator->hasBeenDestroyed()) {
Rohit Grover 1:4769360130ed 564 checkForCorruption(node, file, line, allocator, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 565 allocator->free_memory((char*) memory, file, line);
Rohit Grover 1:4769360130ed 566 }
Rohit Grover 1:4769360130ed 567 }
Rohit Grover 1:4769360130ed 568
Rohit Grover 1:4769360130ed 569 void MemoryLeakDetector::deallocMemory(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 570 {
Rohit Grover 1:4769360130ed 571 deallocMemory(allocator, (char*) memory, UNKNOWN, 0, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 572 }
Rohit Grover 1:4769360130ed 573
Rohit Grover 1:4769360130ed 574 char* MemoryLeakDetector::reallocMemory(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately)
Rohit Grover 1:4769360130ed 575 {
Rohit Grover 1:4769360130ed 576 if (memory) {
Rohit Grover 1:4769360130ed 577 MemoryLeakDetectorNode* node = memoryTable_.removeNode(memory);
Rohit Grover 1:4769360130ed 578 if (node == NULL) {
Rohit Grover 1:4769360130ed 579 outputBuffer_.reportDeallocateNonAllocatedMemoryFailure(file, line, allocator, reporter_);
Rohit Grover 1:4769360130ed 580 return NULL;
Rohit Grover 1:4769360130ed 581 }
Rohit Grover 1:4769360130ed 582 checkForCorruption(node, file, line, allocator, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 583 }
Rohit Grover 1:4769360130ed 584 return reallocateMemoryAndLeakInformation(allocator, memory, size, file, line, allocatNodesSeperately);
Rohit Grover 1:4769360130ed 585 }
Rohit Grover 1:4769360130ed 586
Rohit Grover 1:4769360130ed 587 void MemoryLeakDetector::ConstructMemoryLeakReport(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 588 {
Rohit Grover 1:4769360130ed 589 MemoryLeakDetectorNode* leak = memoryTable_.getFirstLeak(period);
Rohit Grover 1:4769360130ed 590
Rohit Grover 1:4769360130ed 591 outputBuffer_.startMemoryLeakReporting();
Rohit Grover 1:4769360130ed 592
Rohit Grover 1:4769360130ed 593 while (leak) {
Rohit Grover 1:4769360130ed 594 outputBuffer_.reportMemoryLeak(leak);
Rohit Grover 1:4769360130ed 595 leak = memoryTable_.getNextLeak(leak, period);
Rohit Grover 1:4769360130ed 596 }
Rohit Grover 1:4769360130ed 597
Rohit Grover 1:4769360130ed 598 outputBuffer_.stopMemoryLeakReporting();
Rohit Grover 1:4769360130ed 599 }
Rohit Grover 1:4769360130ed 600
Rohit Grover 1:4769360130ed 601 const char* MemoryLeakDetector::report(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 602 {
Rohit Grover 1:4769360130ed 603 outputBuffer_.clear();
Rohit Grover 1:4769360130ed 604 ConstructMemoryLeakReport(period);
Rohit Grover 1:4769360130ed 605
Rohit Grover 1:4769360130ed 606 return outputBuffer_.toString();
Rohit Grover 1:4769360130ed 607 }
Rohit Grover 1:4769360130ed 608
Rohit Grover 1:4769360130ed 609 void MemoryLeakDetector::markCheckingPeriodLeaksAsNonCheckingPeriod()
Rohit Grover 1:4769360130ed 610 {
Rohit Grover 1:4769360130ed 611 MemoryLeakDetectorNode* leak = memoryTable_.getFirstLeak(mem_leak_period_checking);
Rohit Grover 1:4769360130ed 612 while (leak) {
Rohit Grover 1:4769360130ed 613 if (leak->period_ == mem_leak_period_checking) leak->period_ = mem_leak_period_enabled;
Rohit Grover 1:4769360130ed 614 leak = memoryTable_.getNextLeak(leak, mem_leak_period_checking);
Rohit Grover 1:4769360130ed 615 }
Rohit Grover 1:4769360130ed 616 }
Rohit Grover 1:4769360130ed 617
Rohit Grover 1:4769360130ed 618 int MemoryLeakDetector::totalMemoryLeaks(MemLeakPeriod period)
Rohit Grover 1:4769360130ed 619 {
Rohit Grover 1:4769360130ed 620 return memoryTable_.getTotalLeaks(period);
Rohit Grover 1:4769360130ed 621 }