From 50fc10551f25ce34d64bca9711efbca50996c329 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 11 Feb 2014 10:29:01 +0000 Subject: Record mallocs that happen while the memleak finder is disabled. Track them as not leaks, and suppress warnings about realloc() and free() on these blocks, because they are actually tracked. Add missing "throw (std::bad_alloc)" to "operator new" to silence warnings from the llvm compiler. --- lib/common/DebugMemLeakFinder.cpp | 69 +++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/common/DebugMemLeakFinder.cpp b/lib/common/DebugMemLeakFinder.cpp index 0b123675..70026969 100644 --- a/lib/common/DebugMemLeakFinder.cpp +++ b/lib/common/DebugMemLeakFinder.cpp @@ -155,7 +155,17 @@ void *memleakfinder_malloc(size_t size, const char *file, int line) InternalAllocGuard guard; void *b = std::malloc(size); - if(!memleakfinder_global_enable) return b; + + if(!memleakfinder_global_enable) + { + // We may not be tracking this allocation, but if + // someone realloc()s the buffer later then it will + // trigger an untracked buffer warning, which we don't + // want to see either. + memleakfinder_notaleak(b); + return b; + } + if(!memleakfinder_initialised) return b; memleakfinder_malloc_add_block(b, size, file, line); @@ -176,25 +186,58 @@ void *memleakfinder_calloc(size_t blocks, size_t size, const char *file, int lin void *memleakfinder_realloc(void *ptr, size_t size) { + if(!ptr) + { + return memleakfinder_malloc(size, "realloc", 0); + } + + if(!size) + { + memleakfinder_free(ptr); + return NULL; + } + InternalAllocGuard guard; + ASSERT(ptr != NULL); + if(!ptr) return NULL; // defensive + if(!memleakfinder_global_enable || !memleakfinder_initialised) { - return std::realloc(ptr, size); + ptr = std::realloc(ptr, size); + if(!memleakfinder_global_enable) + { + // We may not be tracking this allocation, but if + // someone realloc()s the buffer later then it will + // trigger an untracked buffer warning, which we don't + // want to see either. + memleakfinder_notaleak(ptr); + } + return ptr; } // Check it's been allocated std::map::iterator i(sMallocBlocks.find(ptr)); - if(ptr && i == sMallocBlocks.end()) + std::set::iterator j(sNotLeaks.find(ptr)); + + if(i == sMallocBlocks.end() && j == sNotLeaks.end()) { BOX_WARNING("Block " << ptr << " realloc()ated, but not " "in list. Error? Or allocated in startup static " "objects?"); } + if(j != sNotLeaks.end()) + { + // It's in the list of not-leaks, so don't warn about it, + // but it's being reallocated, so remove it from the list too, + // in case it's reassigned, and add the new block below. + sNotLeaks.erase(j); + } + void *b = std::realloc(ptr, size); - if(ptr && i!=sMallocBlocks.end()) + if(i != sMallocBlocks.end()) { // Worked? if(b != 0) @@ -230,10 +273,19 @@ void memleakfinder_free(void *ptr) { // Check it's been allocated std::map::iterator i(sMallocBlocks.find(ptr)); + std::set::iterator j(sNotLeaks.find(ptr)); + if(i != sMallocBlocks.end()) { sMallocBlocks.erase(i); } + else if(j != sNotLeaks.end()) + { + // It's in the list of not-leaks, so don't warn + // about it, but it's being freed, so remove it + // from the list too, in case it's reassigned. + sNotLeaks.erase(j); + } else { BOX_WARNING("Block " << ptr << " freed, but not " @@ -284,7 +336,8 @@ void memleakfinder_notaleak(void *ptr) ASSERT(!sTrackingDataDestroyed); memleakfinder_notaleak_insert_pre(); - if(memleakfinder_global_enable && memleakfinder_initialised) + + if(memleakfinder_initialised) { sNotLeaks.insert(ptr); } @@ -294,7 +347,9 @@ void memleakfinder_notaleak(void *ptr) sizeof(sNotLeaksPre)/sizeof(*sNotLeaksPre) ) sNotLeaksPre[sNotLeaksPreNum++] = ptr; } -/* { + + /* + { std::map::iterator i(sMallocBlocks.find(ptr)); if(i != sMallocBlocks.end()) sMallocBlocks.erase(i); } @@ -637,7 +692,7 @@ void *operator new(size_t size) } */ -void *operator new[](size_t size) +void *operator new[](size_t size) throw (std::bad_alloc) { return internal_new(size, "standard libraries", 0); } -- cgit v1.2.3