summaryrefslogtreecommitdiff
path: root/lib/common/DebugMemLeakFinder.cpp
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2014-02-11 10:29:01 +0000
committerChris Wilson <chris+github@qwirx.com>2014-02-11 10:29:01 +0000
commit50fc10551f25ce34d64bca9711efbca50996c329 (patch)
treefec9af3063a145e45c535a1610187c3c5b6a797b /lib/common/DebugMemLeakFinder.cpp
parent92a65e002dddef0a5bc1faf3882c4e6cda4611c7 (diff)
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.
Diffstat (limited to 'lib/common/DebugMemLeakFinder.cpp')
-rw-r--r--lib/common/DebugMemLeakFinder.cpp69
1 files changed, 62 insertions, 7 deletions
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<void *, MallocBlockInfo>::iterator i(sMallocBlocks.find(ptr));
- if(ptr && i == sMallocBlocks.end())
+ std::set<void *>::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<void *, MallocBlockInfo>::iterator i(sMallocBlocks.find(ptr));
+ std::set<void *>::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<void *, MallocBlockInfo>::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);
}