X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/ddc3964ed95d01e72229dc9af968a327cd84e56c..13d05b593618882cfc356aef47a4a02fcb857271:/lib/base/eerror.h diff --git a/lib/base/eerror.h b/lib/base/eerror.h index 476029c7..6d38bcc7 100644 --- a/lib/base/eerror.h +++ b/lib/base/eerror.h @@ -1,13 +1,35 @@ #ifndef __E_ERROR__ #define __E_ERROR__ -#include "config.h" #include #include #include #include -void eFatal(const char* fmt, ...); +// to use memleak check change the following in configure.ac +// * add -DMEMLEAK_CHECK and -rdynamic to CPP_FLAGS + +#ifdef MEMLEAK_CHECK +#define BACKTRACE_DEPTH 5 +#include +#include +#include +#include +#include +#include +#endif // MEMLEAK_CHECK + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SWIG +#define CHECKFORMAT __attribute__ ((__format__(__printf__, 1, 2))) +#else +#define CHECKFORMAT +#endif + +void CHECKFORMAT eFatal(const char*, ...); enum { lvlDebug=1, lvlWarning=2, lvlFatal=4 }; @@ -21,12 +43,97 @@ extern int logOutputConsole; #endif #ifdef DEBUG - void eDebug(const char* fmt, ...); - void eDebugNoNewLine(const char* fmt, ...); - void eWarning(const char* fmt, ...); + void CHECKFORMAT eDebug(const char*, ...); + void CHECKFORMAT eDebugNoNewLine(const char*, ...); + void CHECKFORMAT eWarning(const char*, ...); #ifndef SWIG #define ASSERT(x) { if (!(x)) eFatal("%s:%d ASSERTION %s FAILED!", __FILE__, __LINE__, #x); } #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 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); +}; + +void DumpUnfreed(); +#define new new(__FILE__, __LINE__) + +#endif // MEMLEAK_CHECK + #else inline void eDebug(const char* fmt, ...) { @@ -42,4 +149,7 @@ extern int logOutputConsole; #define ASSERT(x) do { } while (0) #endif //DEBUG +void ePythonOutput(const char *); +void eWriteCrashdump(); + #endif // __E_ERROR__