/usr/include/root/MemCheck.h is in libroot-core-dev 5.34.19+dfsg-1.2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | // @(#)root/new:$Id$
// Author: D.Bertini and M.Ivanov 10/08/2000
/*************************************************************************
* Copyright (C) 1995-2001, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//****************************************************************************//
//
//
// MemCheck is used to check the memory in ROOT based applications.
//
// Principe:
// A memory leak often arises whenever memory allocated through
// (new, new[]) is never returned via a corresponding (delete, delete[]).
// Redefining a special version of (operator new, operator delete) will
// allow the bookkeeping of created pointers to chunks of memory and, at
// the same time, pointers to the current function (and all of its callers
// scanning the stack) in order to trace back where the memory is not freed.
// This specific bookkeeping of pointers will be done by a kind of
// "memory info" container class TMemHashTable that will be used via
// the ROOT memory management defined inside the NewDelete.cxx file.
//
// To activate the memory checker you have to set in the .rootrc file
// the resource Root.MemCheck to 1 (e.g.: Root.MemCheck: 1) and you
// have to link with libNew.so (e.g. use root-config --new --libs) or
// use rootn.exe. When all this is the case you will find at the end
// of the program execution a file "memcheck.out" in the directory
// where you started your ROOT program. Alternatively you can set
// the resource Root.MemCheckFile to the name of a file to which
// the leak information will be written. The contents of this
// "memcheck.out" file can be analyzed and transformed into printable
// text via the memprobe program (in $ROOTSYS/bin).
//
// (c) 2000 : Gesellschaft fuer Schwerionenforschung GmbH
// Planckstrasse, 1
// D-64291 Darmstadt
// Germany
//
// Created 10/08/2000 by: D.Bertini and M.Ivanov.
// Based on ideas from LeakTracer by Erwin Andreasen.
//
// - Updated:
// Date: 12/02/2001 Adapt script to new GDB 5.0, new glibc2.2.x and gcc 2.96.
// Date: 23/10/2000 (hash mechanism speeding up the bookkeeping)
//
// - Documentation:
//
// http://www-hades.gsi.de/~dbertini/mem.html
//
//****************************************************************************//
#include "TROOT.h"
class TStackInfo {
public:
UInt_t fSize; //size of the stack
Int_t fTotalAllocCount; //total number of allocation for stack sequence
Int_t fTotalAllocSize; //total size of allocated memory
Int_t fAllocCount; //current number of allocation-deallocation
Int_t fAllocSize; //current allocated size
TStackInfo *fNextHash; //index-pointer to the next info for given hash value
public:
void Init(Int_t stacksize, void **stackptrs); //initialization
void Inc(Int_t memSize); //increment counters -when memory allocated
void Dec(Int_t memSize); //decrement counters -when memory deallocated
ULong_t Hash();
Int_t IsEqual(UInt_t size, void **ptr);
void *StackAt(UInt_t i);
TStackInfo *Next(); //index of the next entries
static ULong_t HashStack(UInt_t size, void **ptr);
};
class TStackTable {
private:
char *fTable; //pointer to the table
TStackInfo **fHashTable; //pointer to the hash table
Int_t fSize; //current size of the table
Int_t fHashSize; //current size of the hash table
Int_t fCount; //number of entries in table
char *fNext; //pointer to the last stack info
void Expand(Int_t newsize);
public:
void Init();
TStackInfo *AddInfo(Int_t size, void **stackptrs);
TStackInfo *FindInfo(Int_t size, void **stackptrs);
Int_t GetIndex(TStackInfo *info);
TStackInfo *GetInfo(Int_t index);
TStackInfo *First() { return (TStackInfo *)fTable; }
};
class TMemInfo {
public:
void *fAddress; //mem address
size_t fSize; //size of the allocated memory
Int_t fStackIndex; //index of the stack info
};
class TMemTable {
public:
Int_t fAllocCount; //number of memory allocation blocks
Int_t fMemSize; //total memory allocated size
Int_t fTableSize; //amount of entries in the below array
Int_t fFirstFreeSpot; //where is the first free spot in the leaks array?
TMemInfo *fLeaks; //leak table
};
class TDeleteTable {
public:
Int_t fAllocCount; //how many memory blocks do we have
Int_t fTableSize; //amount of entries in the below array
TMemInfo *fLeaks; //leak table
};
class TMemHashTable {
public:
static Int_t fgSize; //size of hash table
static TMemTable **fgLeak; //pointer to the hash table
static Int_t fgAllocCount; //number of memory allocation blocks
static TStackTable fgStackTable; //table with stack pointers
static TDeleteTable fgMultDeleteTable; //pointer to the table
~TMemHashTable() { if (TROOT::MemCheck()) Dump(); }
static void Init();
static void RehashLeak(Int_t newSize); //rehash leak pointers
static void *AddPointer(size_t size, void *ptr=0); //add pointer to the table
static void FreePointer(void *p); //free pointer
static void Dump(); //write leaks to the output file
};
inline void TStackInfo::Inc(Int_t memSize)
{
fTotalAllocCount += 1;
fTotalAllocSize += memSize;
fAllocCount += 1;
fAllocSize += memSize;
}
inline void TStackInfo::Dec(int memSize)
{
fAllocCount -= 1;
fAllocSize -= memSize;
}
inline ULong_t TStackInfo::Hash()
{
return HashStack(fSize, (void**)&(this[1]));
}
inline void *TStackInfo::StackAt(UInt_t i)
{
//return i<fSize ? ((char*)&(this[1]))+i*sizeof(void*):0;
void **stptr = (void**)&(this[1]);
return i < fSize ? stptr[i] : 0;
}
inline TStackInfo *TStackInfo::Next()
{
//return (TStackInfo*)((char*)(&this[1])+fSize*sizeof(void*));
return (TStackInfo*)((char*)(this)+fSize*sizeof(void*)+sizeof(TStackInfo));
}
|