summaryrefslogtreecommitdiff
path: root/lib/common/DebugMemLeakFinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common/DebugMemLeakFinder.cpp')
-rw-r--r--lib/common/DebugMemLeakFinder.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/common/DebugMemLeakFinder.cpp b/lib/common/DebugMemLeakFinder.cpp
index 72891cd1..ecc4eb12 100644
--- a/lib/common/DebugMemLeakFinder.cpp
+++ b/lib/common/DebugMemLeakFinder.cpp
@@ -7,11 +7,18 @@
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
#ifndef BOX_RELEASE_BUILD
#include "Box.h"
+=======
+#include "Box.h"
+
+#ifdef BOX_MEMORY_LEAK_TESTING
+
+>>>>>>> 0.12
#undef malloc
#undef realloc
#undef free
@@ -20,11 +27,21 @@
#include <unistd.h>
#endif
+<<<<<<< HEAD
#include <map>
#include <stdio.h>
#include <string.h>
#include <set>
#include <cstdlib> // for std::atexit
+=======
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cstdlib> // for std::atexit
+#include <map>
+#include <set>
+>>>>>>> 0.12
#include "MemLeakFinder.h"
@@ -73,6 +90,16 @@ namespace
size_t sNotLeaksPreNum = 0;
}
+<<<<<<< HEAD
+=======
+void memleakfinder_report_on_signal(int unused)
+{
+ // this is not safe! do not send SIGUSR1 to a process
+ // in a production environment!
+ memleakfinder_report_usage_summary();
+}
+
+>>>>>>> 0.12
void memleakfinder_init()
{
ASSERT(!memleakfinder_initialised);
@@ -84,6 +111,24 @@ void memleakfinder_init()
}
memleakfinder_initialised = true;
+<<<<<<< HEAD
+=======
+
+ #if defined WIN32
+ // no signals, no way to trigger event yet
+ #else
+ struct sigaction newact, oldact;
+ newact.sa_handler = memleakfinder_report_on_signal;
+ newact.sa_flags = SA_RESTART;
+ sigemptyset(&newact.sa_mask);
+ if (::sigaction(SIGUSR1, &newact, &oldact) != 0)
+ {
+ BOX_ERROR("Failed to install USR1 signal handler");
+ THROW_EXCEPTION(CommonException, Internal);
+ }
+ ASSERT(oldact.sa_handler == 0);
+ #endif // WIN32
+>>>>>>> 0.12
}
MemLeakSuppressionGuard::MemLeakSuppressionGuard()
@@ -141,6 +186,19 @@ void *memleakfinder_malloc(size_t size, const char *file, int line)
return b;
}
+<<<<<<< HEAD
+=======
+void *memleakfinder_calloc(size_t blocks, size_t size, const char *file, int line)
+{
+ void *block = memleakfinder_malloc(blocks * size, file, line);
+ if (block != 0)
+ {
+ memset(block, 0, blocks * size);
+ }
+ return block;
+}
+
+>>>>>>> 0.12
void *memleakfinder_realloc(void *ptr, size_t size)
{
InternalAllocGuard guard;
@@ -346,6 +404,88 @@ int memleakfinder_numleaks()
return n;
}
+<<<<<<< HEAD
+=======
+// Summarise all blocks allocated and still allocated, for memory usage
+// diagnostics.
+void memleakfinder_report_usage_summary()
+{
+ InternalAllocGuard guard;
+
+ ASSERT(!sTrackingDataDestroyed);
+
+ typedef std::map<std::string, std::pair<uint64_t, uint64_t> > usage_map_t;
+ usage_map_t usage;
+
+ for(std::map<void *, MallocBlockInfo>::const_iterator
+ i(sMallocBlocks.begin()); i != sMallocBlocks.end(); ++i)
+ {
+ std::ostringstream buf;
+ buf << i->second.file << ":" << i->second.line;
+ std::string key = buf.str();
+
+ usage_map_t::iterator ui = usage.find(key);
+ if(ui == usage.end())
+ {
+ usage[key] = std::pair<uint64_t, uint64_t>(1,
+ i->second.size);
+ }
+ else
+ {
+ ui->second.first++;
+ ui->second.second += i->second.size;
+ }
+ }
+
+ for(std::map<void *, ObjectInfo>::const_iterator
+ i(sObjectBlocks.begin()); i != sObjectBlocks.end(); ++i)
+ {
+ std::ostringstream buf;
+ buf << i->second.file << ":" << i->second.line;
+ std::string key = buf.str();
+
+ usage_map_t::iterator ui = usage.find(key);
+ if(ui == usage.end())
+ {
+ usage[key] = std::pair<uint64_t, uint64_t>(1,
+ i->second.size);
+ }
+ else
+ {
+ ui->second.first++;
+ ui->second.second += i->second.size;
+ }
+ }
+
+ #ifndef DEBUG_LEAKS
+ BOX_WARNING("Memory use: support not compiled in :(");
+ #else
+ if(usage.empty())
+ {
+ BOX_WARNING("Memory use: none detected?!");
+ }
+ else
+ {
+ uint64_t blocks = 0, bytes = 0;
+ BOX_WARNING("Memory use: report follows");
+
+ for(usage_map_t::iterator i = usage.begin(); i != usage.end();
+ i++)
+ {
+ BOX_WARNING("Memory use: " << i->first << ": " <<
+ i->second.first << " blocks, " <<
+ i->second.second << " bytes");
+ blocks += i->second.first;
+ bytes += i->second.second;
+ }
+
+ BOX_WARNING("Memory use: report ends, total: " << blocks <<
+ " blocks, " << bytes << " bytes");
+ }
+ #endif // DEBUG_LEAKS
+}
+
+>>>>>>> 0.12
void memleakfinder_reportleaks_file(FILE *file)
{
InternalAllocGuard guard;
@@ -549,4 +689,8 @@ void operator delete(void *ptr) throw ()
internal_delete(ptr);
}
+<<<<<<< HEAD
#endif // BOX_RELEASE_BUILD
+=======
+#endif // BOX_MEMORY_LEAK_TESTING
+>>>>>>> 0.12