fix
[enigma2.git] / lib / base / eerror.h
index 476029c724d24cb7db30fdf87ac2a791ea59afe0..5a66b31e9735a99f3939a3c928765463c287e53b 100644 (file)
 #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
 
-enum { lvlDebug=1, lvlWarning=2, lvlFatal=4 };
+#ifdef MEMLEAK_CHECK
+#define BACKTRACE_DEPTH 5
+#include <map>
+#include <lib/base/elock.h>
+#include <execinfo.h>
+#include <string>
+#include <new>
+#include <cxxabi.h>
+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;
 
-#ifndef SWIG
-extern Signal2<void, int, const std::string&> logOutput;
-extern int logOutputConsole;
+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
+
+#ifndef NULL
+#define NULL 0
 #endif
 
 #ifdef ASSERT
 #undef ASSERT
 #endif
 
-#ifdef DEBUG
-    void eDebug(const char* fmt, ...);
-    void eDebugNoNewLine(const char* fmt, ...);
-    void eWarning(const char* fmt, ...);
 #ifndef SWIG
+
+#define CHECKFORMAT __attribute__ ((__format__(__printf__, 1, 2)))
+
+extern Signal2<void, int, const std::string&> logOutput;
+extern int logOutputConsole;
+
+void CHECKFORMAT eFatal(const char*, ...);
+enum { lvlDebug=1, lvlWarning=2, lvlFatal=4 };
+
+#ifdef DEBUG
+    void CHECKFORMAT eDebug(const char*, ...);
+    void CHECKFORMAT eDebugNoNewLine(const char*, ...);
+    void CHECKFORMAT eWarning(const char*, ...);
     #define ASSERT(x) { if (!(x)) eFatal("%s:%d ASSERTION %s FAILED!", __FILE__, __LINE__, #x); }
-#endif
-#else
+#else  // DEBUG
     inline void eDebug(const char* fmt, ...)
     {
     }
@@ -39,7 +135,13 @@ extern int logOutputConsole;
     inline void eWarning(const char* fmt, ...)
     {
     }
-    #define ASSERT(x) do { } while (0)
+    #define ASSERT(x) do { x; } while (0)
 #endif //DEBUG
 
+void eWriteCrashdump();
+
+#endif // SWIG
+
+void ePythonOutput(const char *);
+
 #endif // __E_ERROR__