summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-05-30 00:10:26 +0300
committerAndrei Karas <akaras@inbox.ru>2011-05-30 00:10:26 +0300
commita5406f20dba001d4491eb90296c181857c37eabf (patch)
treec85d6de53b28582cce008a6981554763ba464c06
parent4bb36d523c25c2b15f08197f59f2660fe7177508 (diff)
downloadmv-a5406f20dba001d4491eb90296c181857c37eabf.tar.gz
mv-a5406f20dba001d4491eb90296c181857c37eabf.tar.bz2
mv-a5406f20dba001d4491eb90296c181857c37eabf.tar.xz
mv-a5406f20dba001d4491eb90296c181857c37eabf.zip
Improve memory leak detector.
Add /dump chat command.
-rw-r--r--src/commandhandler.cpp6
-rw-r--r--src/debug.h1
-rw-r--r--src/debug/debug_new.cpp46
3 files changed, 41 insertions, 12 deletions
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
index ece2ccb44..276cd741a 100644
--- a/src/commandhandler.cpp
+++ b/src/commandhandler.cpp
@@ -1157,6 +1157,12 @@ void CommandHandler::handleDump(const std::string &args,
+ toString(res->size()));
}
}
+#elif defined ENABLE_MEM_DEBUG
+void CommandHandler::handleDump(const std::string &args _UNUSED_,
+ ChatTab *tab _UNUSED_)
+{
+ check_leaks();
+}
#else
void CommandHandler::handleDump(const std::string &args _UNUSED_,
ChatTab *tab _UNUSED_)
diff --git a/src/debug.h b/src/debug.h
index 0e8e19961..e89f8278e 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -20,6 +20,5 @@
#ifdef ENABLE_MEM_DEBUG
#define _DEBUG_NEW_EMULATE_MALLOC 1
-
#include "debug/debug_new.h"
#endif
diff --git a/src/debug/debug_new.cpp b/src/debug/debug_new.cpp
index 98c44264e..3bc02b3e5 100644
--- a/src/debug/debug_new.cpp
+++ b/src/debug/debug_new.cpp
@@ -55,6 +55,8 @@
#include "debug/fast_mutex.h"
#include "debug/static_assert.h"
+//define DUMP_MEM_ADDRESSES 1
+
#if !_FAST_MUTEX_CHECK_INITIALIZATION && !defined(_NOTHREADS)
#error "_FAST_MUTEX_CHECK_INITIALIZATION not set: check_leaks may not work"
#endif
@@ -220,6 +222,7 @@ struct new_ptr_list_t
unsigned line :31;
unsigned is_array :1;
unsigned magic;
+ unsigned dumped;
};
/**
@@ -249,7 +252,8 @@ static new_ptr_list_t new_ptr_list =
},
0,
0,
- MAGIC
+ MAGIC,
+ false
};
/**
@@ -501,6 +505,7 @@ static void* alloc_mem(size_t size, const char* file, int line, bool is_array)
new_ptr_list.prev->next = ptr;
new_ptr_list.prev = ptr;
}
+ ptr->dumped = 0;
#if _DEBUG_NEW_TAILCHECK
memset((char*)pointer + size, _DEBUG_NEW_TAILCHECK_CHAR,
_DEBUG_NEW_TAILCHECK);
@@ -608,9 +613,14 @@ static void free_pointer(void* pointer, void* addr, bool is_array)
int check_leaks()
{
int leak_cnt = 0;
+ int dumped_cnt = 0;
+ int new_cnt = 0;
+ unsigned long new_size = 0;
fast_mutex_autolock lock_ptr(new_ptr_lock);
fast_mutex_autolock lock_output(new_output_lock);
new_ptr_list_t* ptr = new_ptr_list.next;
+ fprintf(new_output_fp, "---LEAKS LIST---\n");
+
while (ptr != &new_ptr_list)
{
const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
@@ -628,20 +638,34 @@ int check_leaks()
pointer);
}
#endif
- fprintf(new_output_fp,
- "Leaked object at %p (size %u, ",
- pointer,
- (unsigned)ptr->size);
+#ifndef DUMP_MEM_ADDRESSES
if (ptr->line != 0)
- print_position(ptr->file, ptr->line);
- else
- print_position(ptr->addr, ptr->line);
- fprintf(new_output_fp, ")\n");
+#endif
+ {
+ fprintf(new_output_fp,
+ "Leaked object at %p (size %u, dump %u, ",
+ pointer, (unsigned)ptr->size, ptr->dumped);
+ if (ptr->line != 0)
+ print_position(ptr->file, ptr->line);
+ else
+ print_position(ptr->addr, ptr->line);
+ fprintf(new_output_fp, ")\n");
+ ++ new_cnt;
+ new_size += (unsigned long)ptr->size;
+ }
+ if (ptr->dumped)
+ ++ dumped_cnt;
+
+ ++ ptr->dumped;
ptr = ptr->next;
- ++leak_cnt;
+ ++ leak_cnt;
}
if (new_verbose_flag || leak_cnt)
- fprintf(new_output_fp, "*** %d leaks found\n", leak_cnt);
+ {
+ fprintf(new_output_fp, "*** %d leaks found, new %d "
+ "(size %lu), dumped count %d\n", leak_cnt, new_cnt,
+ new_size, dumped_cnt);
+ }
return leak_cnt;
}