[Box Backup-commit] COMMIT r3168 - box/trunk/lib/common

subversion at boxbackup.org subversion at boxbackup.org
Wed Feb 13 00:27:54 GMT 2013


Author: chris
Date: 2013-02-13 00:27:54 +0000 (Wed, 13 Feb 2013)
New Revision: 3168

Modified:
   box/trunk/lib/common/Box.h
   box/trunk/lib/common/DebugMemLeakFinder.cpp
   box/trunk/lib/common/MemLeakFinder.h
Log:
Add ability to generate memory usage reports while running.

* ./configure CXXFLAGS=-DDEBUG_LEAKS
* Build and run the binary as normal (release or debug)
* Send SIGUSR1 to the process (e.g. killall -USR1 bbstored)
* Check the system logs, or the console.

Not safe for use on a production process, as it does illegal things in
a signal handler that may result in the process hanging. Use only for
debugging, and be prepared to kill any stuck processes.


Modified: box/trunk/lib/common/Box.h
===================================================================
--- box/trunk/lib/common/Box.h	2013-02-13 00:24:11 UTC (rev 3167)
+++ box/trunk/lib/common/Box.h	2013-02-13 00:27:54 UTC (rev 3168)
@@ -40,7 +40,6 @@
 #include "Logging.h"
 
 #ifndef BOX_RELEASE_BUILD
-	
 	extern bool AssertFailuresToSyslog;
 	#define ASSERT_FAILS_TO_SYSLOG_ON {AssertFailuresToSyslog = true;}
 	void BoxDebugAssertFailed(const char *cond, const char *file, int line);
@@ -71,7 +70,6 @@
 	
 	// Exception names
 	#define EXCEPTION_CODENAMES_EXTENDED
-	
 #else
 	#define ASSERT_FAILS_TO_SYSLOG_ON
 	#define ASSERT(cond)
@@ -82,9 +80,20 @@
 	// Box Backup builds release get extra information for exception logging
 	#define EXCEPTION_CODENAMES_EXTENDED
 	#define EXCEPTION_CODENAMES_EXTENDED_WITH_DESCRIPTION
-	
 #endif
 
+#if defined DEBUG_LEAKS
+	#ifdef PLATFORM_DISABLE_MEM_LEAK_TESTING
+		#error Compiling with DEBUG_LEAKS enabled, but not supported on this platform
+	#else
+		#define BOX_MEMORY_LEAK_TESTING
+	#endif
+#elif defined BOX_RELEASE_BUILD
+	#ifndef PLATFORM_DISABLE_MEM_LEAK_TESTING
+		#define BOX_MEMORY_LEAK_TESTING
+	#endif
+#endif // DEBUG_LEAKS || BOX_RELEASE_BUILD
+
 #ifdef BOX_MEMORY_LEAK_TESTING
 	// Memory leak testing
 	#include "MemLeakFinder.h"

Modified: box/trunk/lib/common/DebugMemLeakFinder.cpp
===================================================================
--- box/trunk/lib/common/DebugMemLeakFinder.cpp	2013-02-13 00:24:11 UTC (rev 3167)
+++ box/trunk/lib/common/DebugMemLeakFinder.cpp	2013-02-13 00:27:54 UTC (rev 3168)
@@ -7,11 +7,10 @@
 //
 // --------------------------------------------------------------------------
 
+#include "Box.h"
 
-#ifndef BOX_RELEASE_BUILD
+#ifdef BOX_MEMORY_LEAK_TESTING
 
-#include "Box.h"
-
 #undef malloc
 #undef realloc
 #undef free
@@ -20,11 +19,13 @@
 	#include <unistd.h>
 #endif
 
-#include <map>
+#include <signal.h>
 #include <stdio.h>
 #include <string.h>
+
+#include <cstdlib> // for std::atexit
+#include <map>
 #include <set>
-#include <cstdlib> // for std::atexit
 
 #include "MemLeakFinder.h"
 
@@ -73,6 +74,13 @@
 	size_t sNotLeaksPreNum = 0;
 }
 
+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();
+}
+
 void memleakfinder_init()
 {
 	ASSERT(!memleakfinder_initialised);
@@ -84,6 +92,21 @@
 	}
 
 	memleakfinder_initialised = true;
+
+	#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
 }
 
 MemLeakSuppressionGuard::MemLeakSuppressionGuard()
@@ -346,6 +369,85 @@
 	return n;
 }
 
+// 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
+}
+
 void memleakfinder_reportleaks_file(FILE *file)
 {
 	InternalAllocGuard guard;
@@ -549,4 +651,4 @@
 	internal_delete(ptr);
 }
 
-#endif // BOX_RELEASE_BUILD
+#endif // BOX_MEMORY_LEAK_TESTING

Modified: box/trunk/lib/common/MemLeakFinder.h
===================================================================
--- box/trunk/lib/common/MemLeakFinder.h	2013-02-13 00:24:11 UTC (rev 3167)
+++ box/trunk/lib/common/MemLeakFinder.h	2013-02-13 00:27:54 UTC (rev 3168)
@@ -36,6 +36,8 @@
 
 int memleakfinder_numleaks();
 
+void memleakfinder_report_usage_summary();
+
 void memleakfinder_reportleaks();
 
 void memleakfinder_reportleaks_appendfile(const char *filename, const char *markertext);




More information about the Boxbackup-commit mailing list