+#endif
+
+#ifdef MEMLEAK_CHECK
+typedef struct
+{
+ unsigned int address;
+ unsigned int size;
+ char *file;
+ void *backtrace[BACKTRACE_DEPTH];
+ unsigned char btcount;
+ unsigned short line;
+ unsigned char type;
+} ALLOC_INFO;
+
+typedef std::map<unsigned int, ALLOC_INFO> AllocList;
+
+extern AllocList *allocList;
+extern pthread_mutex_t memLock;
+
+static inline void AddTrack(unsigned int addr, unsigned int asize, const char *fname, unsigned int lnum, unsigned int type)
+{
+ ALLOC_INFO info;
+
+ if(!allocList)
+ allocList = new(AllocList);
+
+ info.address = addr;
+ info.file = strdup(fname);
+ info.line = lnum;
+ info.size = asize;
+ info.type = type;
+ info.btcount = backtrace( info.backtrace, BACKTRACE_DEPTH );
+ singleLock s(memLock);
+ (*allocList)[addr]=info;
+};
+
+static inline void RemoveTrack(unsigned int addr, unsigned int type)
+{
+ if(!allocList)
+ return;
+ AllocList::iterator i;
+ singleLock s(memLock);
+ i = allocList->find(addr);
+ if ( i != allocList->end() )
+ {
+ if ( i->second.type != type )
+ i->second.type=3;
+ else
+ {
+ free(i->second.file);
+ allocList->erase(i);
+ }
+ }
+};
+
+inline void * operator new(unsigned int size, const char *file, int line)
+{
+ void *ptr = (void *)malloc(size);
+ AddTrack((unsigned int)ptr, size, file, line, 1);
+ return(ptr);
+};
+
+inline void operator delete(void *p)
+{
+ RemoveTrack((unsigned int)p,1);
+ free(p);
+};
+
+inline void * operator new[](unsigned int size, const char *file, int line)
+{
+ void *ptr = (void *)malloc(size);
+ AddTrack((unsigned int)ptr, size, file, line, 2);
+ return(ptr);
+};
+
+inline void operator delete[](void *p)
+{
+ RemoveTrack((unsigned int)p, 2);
+ free(p);
+};
+
+inline void DumpUnfreed()
+{
+ AllocList::iterator i;
+ unsigned int totalSize = 0;
+
+ if(!allocList)
+ return;
+
+ for(i = allocList->begin(); i != allocList->end(); i++)
+ {
+ unsigned int tmp;
+ printf("%s\tLINE %d\tADDRESS %p\t%d unfreed\ttype %d\n",
+ i->second.file, i->second.line, (void*)i->second.address, i->second.size, i->second.type);
+ totalSize += i->second.size;
+ char **bt_string = backtrace_symbols( i->second.backtrace, i->second.btcount );
+ for ( tmp=0; tmp < i->second.btcount; tmp++ )
+ {
+ if ( bt_string[tmp] )
+ {
+#ifdef HAVE_CPP_FILT
+ char *beg = strchr(bt_string[tmp], '(');
+ if ( beg )
+ {
+ std::string tmp1(beg+1);
+ int pos1=tmp1.find('+'), pos2=tmp1.find(')');
+ std::string tmp2(tmp1.substr(pos1,(pos2-pos1)-1));
+ std::string cmd="c++filt ";
+ cmd+=tmp1.substr(0,pos1);
+ FILE *f = popen(cmd.c_str(), "r");
+ char buf[256];
+ if (f)
+ {
+ size_t rd = fread(buf, 1, 255, f);
+ if ( rd > 0 )
+ {
+ buf[rd-1]=0;
+ printf("%s %s\n", buf, tmp2.c_str() );
+ }
+ else
+ printf("%s\n", tmp1.substr(0,pos1).c_str());
+ fclose(f);
+ }
+ }
+ else
+#endif // HAVE_CPP_FILT
+ printf("%s\n", bt_string[tmp]);
+ }
+ }
+ free(bt_string);
+ printf("\n");
+ }
+
+ printf("-----------------------------------------------------------\n");
+ printf("Total Unfreed: %d bytes\n", totalSize);
+ fflush(stdout);
+};
+#define new new(__FILE__, __LINE__)
+
+#endif // MEMLEAK_CHECK
+
+