Unit Testing framework based on http://cpputest.github.io/

CppUTest

Where to find more information

Getting test reports on the console

You may need to tailor the file src/Platforms/mbed/UtestPlatform.cpp to your needs. In particular, if you want console output, you might want to look at the function PlatformSpecificPutchar().

Quick introduction (some code!)

To write your first test, all you need is a new cpp file with a TEST_GROUP and a TEST, like:

#include "CppUTest/TestHarness.h"

TEST_GROUP(FirstTestGroup)
{
};

TEST(FirstTestGroup, FirstTest)
{
   FAIL("Fail me!");
}

This test will fail.

You can add new tests to the test group by just writing more tests in the file, like this:

TEST(FirstTestGroup, SecondTest)
{
   STRCMP_EQUAL("hello", "world");
   LONGS_EQUAL(1, 2);
   CHECK(false);
}

You do need to trigger the tests from somewhere in your program. It could look something like:

#include "CppUTest/TestRegistry.h"
#include "CppUTest/CommandLineTestRunner.h"

int main(int ac, char** av)
{
    ....
    unsigned failureCount = 0;
    {
        ConsoleTestOutput output;
        CommandLineTestRunner runner(ac, av, &output, TestRegistry::getCurrentRegistry());
        failureCount = runner.runAllTestsMain();
    }

    if (failureCount == 0) {
        console.printf("PASSED\r\n");
    }
    ...
}

For more information, We’d recommend to read the manual or, even better, check some existing tests such as SimpleStringTest or (a bit more complicated) MemoryLeakDetectorTest or the mocking tests or just check out the Cheat Sheet.

Committer:
Rohit Grover
Date:
Thu Jun 19 08:24:31 2014 +0100
Revision:
2:82161d9e7b36
Parent:
1:4769360130ed
uncomment the code in CommandLineTestRunner::RunAllTests() having to do with MemoryLeakWarningPlugin

Bas Vodde, from the CppUTest development team has suggested an alternate way to run tests.

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 }