From subversion at boxbackup.org Wed Feb 13 00:24:12 2013 From: subversion at boxbackup.org (subversion at boxbackup.org) Date: Wed, 13 Feb 2013 00:24:12 GMT Subject: [Box Backup-commit] COMMIT r3167 - box/trunk/test/bbackupd Message-ID: <201302130024.r1D0OCjd009023@wm.boxbackup.org> Author: chris Date: 2013-02-13 00:24:11 +0000 (Wed, 13 Feb 2013) New Revision: 3167 Modified: box/trunk/test/bbackupd/testbbackupd.cpp Log: Fix compile error due to missing mode on open(O_CREAT). Modified: box/trunk/test/bbackupd/testbbackupd.cpp =================================================================== --- box/trunk/test/bbackupd/testbbackupd.cpp 2012-11-27 22:56:44 UTC (rev 3166) +++ box/trunk/test/bbackupd/testbbackupd.cpp 2013-02-13 00:24:11 UTC (rev 3167) @@ -1201,7 +1201,7 @@ std::string touchfile = "testfiles/TestDir1/spacetest/d1/touch-me"; - fd = open(touchfile.c_str(), O_CREAT | O_WRONLY); + fd = open(touchfile.c_str(), O_CREAT | O_WRONLY, 0700); TEST_THAT(fd > 0); // write again, to update the file's timestamp TEST_EQUAL_LINE(sizeof(buffer), From subversion at boxbackup.org Wed Feb 13 00:27:54 2013 From: subversion at boxbackup.org (subversion at boxbackup.org) Date: Wed, 13 Feb 2013 00:27:54 GMT Subject: [Box Backup-commit] COMMIT r3168 - box/trunk/lib/common Message-ID: <201302130027.r1D0Rsbh009052@wm.boxbackup.org> 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 #endif -#include +#include #include #include + +#include // for std::atexit +#include #include -#include // 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 > usage_map_t; + usage_map_t usage; + + for(std::map::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(1, + i->second.size); + } + else + { + ui->second.first++; + ui->second.second += i->second.size; + } + } + + for(std::map::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(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);