39#define BLOCXX_MEMTRACER_CPP_INCLUDE_GUARD_
40#include "blocxx/BLOCXX_config.h"
41#ifdef BLOCXX_DEBUG_MEMORY
50#ifdef BLOCXX_HAVE_UNISTD_H
54#define BLOCXX_MEM_SIG 0xaaaaaaaa
55#define BLOCXX_FREE_MEM_SIG 0xbbbbbbbb
65 typedef std::size_t size_type;
66 typedef std::ptrdiff_t difference_type;
68 typedef value_type* pointer;
69 typedef const value_type* const_pointer;
70 typedef value_type& reference;
71 typedef const value_type& const_reference;
72 template <
class U>
struct rebind
74 typedef MemTracerAllocator<U> other;
79 pointer
address(reference
r)
const {
return &
r; }
80 const_pointer
address(const_reference
r)
const {
return &
r; }
89 size_type max_size()
const throw() {
return static_cast<size_type
>(-1); }
90 void construct(pointer
p, const_reference val) {
new(
p) value_type(val); }
91 void destroy(pointer
p) {
p->~value_type(); }
97static const char*
const noFile =
"<no file>";
104 Entry (
char const * file,
int line,
size_t sz)
105 :
m_file(file), m_line(line), m_size(sz), m_isDeleted(
false) {}
107 :
m_file(NULL), m_line(-1), m_size(0), m_isDeleted(
false) {}
108 char const* getFile()
const {
return m_file; }
109 int getLine()
const {
return m_line; }
110 size_t getSize()
const {
return m_size; }
111 void setDeleted() { m_isDeleted =
true; }
112 bool isDeleted() {
return m_isDeleted; }
123 Lock(MemTracer & tracer) : m_tracer(tracer) { m_tracer.lock (); }
139 typedef std::map<void*, Entry, std::less<void*>,
alloc_t >
map_t;
140 typedef map_t::iterator iterator;
146 void* remove(
void *
p);
162static bool noFree =
false;
172 fprintf(
stderr,
"*******************************************************************************\n");
174 fprintf(
stderr,
"*******************************************************************************\n");
176 fprintf(
stderr,
"-------------------------------------------------------------------------------\n");
178 fprintf(
stderr,
"-------------------------------------------------------------------------------\n");
192 if (
getenv(
"BLOCXX_MEM_DISABLE") &&
getenv(
"BLOCXX_MEM_DISABLE")[0] ==
'1')
196 if (
getenv(
"BLOCXX_MEM_NOFREE") &&
getenv(
"BLOCXX_MEM_NOFREE")[0] ==
'1')
200 if (
getenv(
"BLOCXX_MEM_AGGRESSIVE") &&
getenv(
"BLOCXX_MEM_AGGRESSIVE")[0] ==
'1')
246MemTracer::~MemTracer()
264 unsigned long*
plong = (
unsigned long*)((
char*)
p - 4);
268 "Sig is %x\n", (
unsigned int)*
plong);
272 plong = (
unsigned long*)((
char*)
p +
sz);
276 "Sig is %x\n", (
unsigned int)*
plong);
281 return (
void*)((
char*)
p - 4);
289 unsigned long*
plong = (
unsigned long*)((
char*)
p - 4);
293 "Sig is %x\n", (
unsigned int)*
plong);
297 plong = (
unsigned long*)((
char*)
p +
sz);
301 "Sig is %x\n", (
unsigned int)*
plong);
305 return (
void*)((
char*)
p - 4);
313 if (!
it->second.isDeleted())
321MemTracer::add(
void*
p,
char const*
file,
int line,
size_t sz)
332MemTracer::remove(
void*
p)
339 if (
it->second.isDeleted())
341 fprintf(
stderr,
"DOUBLE DELETE (NOFREE): Attempting to double "
342 "delete memory at: %p\n",
p);
347 void*
pfile = (
void*)
it->second.getFile();
350 it->second.setDeleted();
362 fprintf(
stderr,
"Attempting to delete memory not in map: %p\n",
p);
366 unsigned long*
plong = (
unsigned long*)((
char*)
p - 4);
374 fprintf(
stderr,
"DOUBLE DELETE: This memory was previously freed by MemTracer, "
375 "probably double delete\n");
386MemTracer::printEntry(
void*
p)
396MemTracer::getEntry(
void*
idx)
400 MemTracer::Entry
rval;
413 if (
m_map.size() != 0)
415 fprintf(
stderr,
"**** %lu MEMORY LEAK(S) DETECTED\n",
static_cast<unsigned long>(
m_map.size()));
419 if (!
it->second.isDeleted())
423 fprintf(
stderr,
"\tSIZE: %lu",
static_cast<unsigned long>(
it->second.getSize()));
428 fprintf(
stderr,
"***** END MEMORY LEAKS - TOTAL MEMORY LEAKED = %lu\n",
static_cast<unsigned long>(
total));
436 unsigned long*
plong = (
unsigned long*)
p;
438 plong = (
unsigned long*)((
char*)
p + size + 4);
440 p = (
void*)((
char*)
p + 4);
457 "Possible bug in MemTracer.\n");
526 printf(
"** MemTracer can't remove delete from map: ADDR: %p\n",
p);
546operator new[](std::size_t size,
char const* file,
int line)
throw(std::bad_alloc)
552operator new(std::size_t size,
char const* file,
int line)
throw(std::bad_alloc)
558operator new[](std::size_t size)
throw(std::bad_alloc)
564operator new(std::size_t size)
throw(std::bad_alloc)
569operator delete(
void* p)
574operator delete[](
void* p)
bool operator==(const Array< T > &x, const Array< T > &y)