optimize code
[enigma2.git] / lib / base / eerror.h
index 476029c..6d38bcc 100644 (file)
@@ -1,13 +1,35 @@
 #ifndef __E_ERROR__
 #define __E_ERROR__
 
-#include "config.h"
 #include <string>
 #include <map>       
 #include <new>
 #include <libsig_comp.h>
 
-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 <map>
+#include <lib/base/elock.h>
+#include <execinfo.h>
+#include <string>
+#include <new>
+#include <cxxabi.h>
+#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<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);
+};
+
+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__