Index: src/Helpers/MemDebug.cpp
===================================================================
--- src/Helpers/MemDebug.cpp	(revision 112b090c14e4507fb9dde0a3a340b9a3d61823ba)
+++ src/Helpers/MemDebug.cpp	(revision 6d6b5491705c9d7eaf181c02b89e656d2ad2ae18)
@@ -10,4 +10,9 @@
 #include <cstring>
 #include <boost/thread.hpp>
+
+#ifdef __GNUC__
+#include <execinfo.h>
+#include <cxxabi.h>
+#endif
 
 using namespace std;
@@ -34,4 +39,9 @@
       char file[length+1];
       int line;
+#ifdef __GNUC__  // function tracking only works with GCC
+      // function names can get looooong
+      enum {length2 = 256};
+      char function[length2+1];
+#endif
       size_t nbytes;
       bool isUsed;
@@ -96,5 +106,10 @@
     for(entry_t *pos=begin;pos;pos=pos->next){
       cout << "\nChunk of " << pos->info.nbytes << " bytes" << " still available" << endl;
+#ifdef __GNUC__
+      cout << "Chunk reserved at: " << pos->info.function
+           << " (" << pos->info.file << ":" << pos->info.line  << ")" << endl;
+#else
       cout << "Chunk reserved at: " << pos->info.file << ":" << pos->info.line << endl;
+#endif
     }
   }
@@ -130,5 +145,156 @@
     deleteEntry(entry);
   }
-}
+
+#ifdef __GNUC__
+  // this function let's us find the caller's name
+  char* getCaller(){
+    // stack looks like this:
+    // getCaller();
+    // operator new();
+    // function_we_are_looking_for(); <-
+    const size_t max_depth = 3;
+    void* stack_addrs[max_depth];
+    size_t stack_depth;
+    char **stack_strings=0;
+    const char *func_name=0;
+    const char *toplevel = "Global scope";
+    char *retval=0;
+
+    // get the backtrace, depth three
+    stack_depth   = backtrace(stack_addrs,max_depth);
+    stack_strings = backtrace_symbols(stack_addrs, stack_depth);
+    // used later for demangling
+    // reserved here, so we can free it unconditionally
+    char *dm_function = static_cast<char*>(malloc(entry_t::info_t::length2));
+    if(!dm_function){
+      // malloc failed... we are out of luck
+      throw std::bad_alloc();
+    }
+
+    // see if we found our function name
+    if(stack_depth==max_depth){
+      // find the mangled function name
+      char *begin = stack_strings[max_depth-1];
+      // function name starts with a (
+      while(*begin && *begin!='(') ++begin;
+      char *end=begin;
+      while(*end && *end!='+') ++end;
+
+      // see if we found our function name
+      if(*begin && *end){
+        *begin++ = 0;
+        *end = 0;
+        // use the C++ demangler
+
+        size_t sz = entry_t::info_t::length2;
+        int status;
+        char *func_ret = abi::__cxa_demangle(begin, dm_function, &sz, &status);
+        if(func_ret){
+          // abi might have realloced...
+          dm_function = func_ret;
+          func_name = dm_function;
+        }
+        else{
+          // demangling failed... get the function name without demangling
+          func_name = begin;
+        }
+      }
+      else{
+        // function name not found... get the whole line
+        func_name = stack_strings[max_depth-1];
+      }
+
+    }
+    else{
+      func_name = toplevel;
+    }
+
+    // now we copy the desired function name
+    if((retval = static_cast<char*>(malloc(strlen(func_name)+1)))){
+      // we know that the string will fit, so strcpy is safe here
+      strcpy(retval,func_name);
+    }
+    else{
+      free(stack_strings); // malloc()ed by backtrace_symbols
+      free(dm_function);
+      // uh-uh ... seems we are out of luck for allocations now
+      throw std::bad_alloc();
+    }
+    free(dm_function);
+    free(stack_strings); // malloc()ed by backtrace_symbols
+    return retval;
+  }
+#endif
+}
+
+#ifdef __GNUC__
+
+void *operator new(size_t nbytes,const char* file, int line, const char* func) throw(std::bad_alloc) {
+
+  // we need to lock, so that no one changes the linked list while we are here
+  boost::mutex::scoped_lock guard(Memory::memorylock);
+
+  // to avoid allocations of 0 bytes if someone screws up
+  // allocation with 0 byte size are undefined behavior, so we are
+  // free to handle it this way
+  if(!nbytes) {
+    nbytes = 1;
+  }
+
+  // get the size of the entry, including alignment
+  static const size_t entrySpace = Memory::doAlign(sizeof(Memory::entry_t));
+
+  void *res;
+  if(!(res=malloc(entrySpace + nbytes))){
+    // new must throw, when space is low
+    throw std::bad_alloc();
+  }
+
+  // we got the space, so update the global info
+  Memory::state += nbytes;
+  if(Memory::state>Memory::max){
+    Memory::max = Memory::state;
+  }
+  Memory::allocs++;
+
+  // build the entry in front of the space
+  Memory::entry_t *entry = (Memory::entry_t*) res;
+  memset(res,0,entrySpace);
+  entry->info.nbytes = nbytes;
+  entry->info.isUsed = true;
+  strncpy(entry->info.file,file,Memory::entry_t::info_t::length);
+  entry->info.file[Memory::entry_t::info_t::length] = '\0';
+  entry->info.line=line;
+  strncpy(entry->info.function,func,Memory::entry_t::info_t::length2);
+  entry->info.function[Memory::entry_t::info_t::length2] = '\0';
+  // the space starts behind the info
+  entry->info.location = (char*)res + entrySpace;
+
+  // add the entry at the end of the list
+  entry->next=0;            // the created block is last in the list
+  entry->prev=Memory::end;  // the created block is last in the list
+  if(!Memory::begin){
+    // the list was empty... start a new one
+    Memory::begin=entry;
+  }
+  else {
+    // other blocks present... we can add to the last one
+    Memory::end->next=entry;
+  }
+  Memory::end=entry;
+
+  // get the checksum...
+  entry->checksum = Memory::calcChecksum(&entry->info);
+  // this will be set to true, when the block is removed from
+  // the list for any reason
+  entry->isIgnored = false;
+
+  // ok, space is prepared... the user can have it.
+  // the rest (constructor, deleting when something is thrown etc)
+  // is handled automatically
+  return entry->info.location;
+}
+
+#else
 
 void *operator new(size_t nbytes,const char* file, int line) throw(std::bad_alloc) {
@@ -196,9 +362,38 @@
 }
 
+#endif
+
 void *operator new(size_t nbytes) throw(std::bad_alloc) {
   // Just forward to the other operator, when we do not know from
   // where the allocation came
+#ifdef __GNUC__
+  // this might throw bad_alloc
+  char *caller = Memory::getCaller();
+  void* retval = 0;
+
+  // if this throws, we have to clean up the caller anyway
+  try{
+    retval = operator new(nbytes,"Unknown",0,caller);
+  }
+  catch(...)
+  {
+    free(caller); // malloc()ed by Memory::getCaller();
+    throw;
+  }
+  free(caller); // malloc()ed by Memory::getCaller();
+  return retval;
+#else
   return operator new(nbytes,"Unknown",0);
-}
+#endif
+}
+
+#ifdef __GNUC__
+
+void *operator new[] (size_t nbytes,const char* file, int line, const char* func) throw(std::bad_alloc) {
+  // The difference between new and new[] is just for compiler bookkeeping.
+  return operator new(nbytes,file,line,func);
+}
+
+#else
 
 void *operator new[] (size_t nbytes,const char* file, int line) throw(std::bad_alloc) {
@@ -207,7 +402,27 @@
 }
 
+#endif
+
 void *operator new[] (size_t nbytes) throw(std::bad_alloc) {
   // Forward again
+#ifdef __GNUC__
+  // this might throw bad_alloc
+    char *caller = Memory::getCaller();
+    void *retval=0;
+
+    // if this throws, we have to clean up the caller anyway
+    try{
+      retval = operator new[] (nbytes,"Unknown",0,caller);
+    }
+    catch(...)
+    {
+      free(caller); // malloc()ed by Memory::getCaller();
+      throw;
+    }
+    free(caller); // malloc()ed by Memory::getCaller();
+    return retval;
+#else
   return operator new[] (nbytes,"Unknown",0);
+#endif
 }
 
Index: src/Helpers/MemDebug.hpp
===================================================================
--- src/Helpers/MemDebug.hpp	(revision 112b090c14e4507fb9dde0a3a340b9a3d61823ba)
+++ src/Helpers/MemDebug.hpp	(revision 6d6b5491705c9d7eaf181c02b89e656d2ad2ae18)
@@ -60,9 +60,15 @@
   }
 }
-
+#ifdef __GNUC__
+void *operator new   (size_t nbytes,const char* file, int line, const char* func) throw(std::bad_alloc);
+void *operator new[] (size_t nbytes,const char* file, int line, const char* func) throw(std::bad_alloc);
+#else
 void *operator new   (size_t nbytes,const char* file, int line) throw(std::bad_alloc);
 void *operator new[] (size_t nbytes,const char* file, int line) throw(std::bad_alloc);
+#endif
 void operator delete   (void *ptr,const char*, int) throw();
 void operator delete[] (void *ptr,const char*, int) throw();
+
+
 
 /**
@@ -70,5 +76,9 @@
  * version that allows tracking.
  */
+#ifdef __GNUC__
+#define new new(__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#else
 #define new new(__FILE__,__LINE__)
+#endif
 
 #endif
