#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;
+ const 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 = fname;
+ info.line = lnum;
+ info.size = asize;
+ info.type = type;
+ info.btcount = 0; //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
+ allocList->erase(i);
+ }
+};
+
+inline void * operator new(size_t 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[](size_t 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, ...)
{
}
#define ASSERT(x) do { } while (0)
#endif //DEBUG
+void eWriteCrashdump();
+
+#endif // SWIG
+
+void ePythonOutput(const char *);
+
#endif // __E_ERROR__