#include #include #include #include using namespace std; struct ALLOCITEM{ unsigned long addr; int size; string line; ALLOCITEM(unsigned long _addr, int _size, const char *pt) { addr = _addr; size = _size; line = pt; } }; static bool operator < (const ALLOCITEM &p1, const ALLOCITEM &p2) { //fprintf (stderr,"compare :%s: :%s: %d\n",p1.addr.c_str(),p2.addr.c_str() // ,p1.addr < p2.addr); return p1.addr < p2.addr; } int main (int argc, char *argv[]) { glocal bool stats = false; glocal bool report = false; glocal bool invalid = false; int ret = (argc, argv); setproginfo ("showleak",PACKAGE_REV ,"showleak [ options ] logfile\n" "\n" "Process a log produced by mapmalloc and remove\n" "entries which have been freed. The remaining one are printed\n" "and are memory leak.\n" "\n" "Using option -r, the output is written in the same format\n" "as the input, so is suitable for use with maplog.\n"); setarg ('i',"invalid","Print the list of invalid free or realloc" ,glocal.invalid,false); setarg ('s',"stats","Produce some statistics",glocal.stats,false); setarg ('r',"report","Prints the list of leaked allocations" ,glocal.report,false); int ret = -1; if (argc != 1){ usage(); }else if (glocal.invalid && glocal.report){ fprintf (stderr,"Option --invalid and --report may not be used at the same time\n"); }else{ glocal set items; glocal unsigned long sofar = 0; glocal unsigned long nbmalloc = 0; glocal unsigned long maxalloc = 0; glocal unsigned long total = 0; ret = (argv[0],true); const char *cmd = line + 18; if (strncmp(cmd,"malloc",6)==0 || strncmp(cmd,"calloc",6)==0 || strncmp(cmd,"strdup",6)==0){ unsigned long addr; int size; sscanf (cmd+6,"%8lx %d",&addr,&size); glocal.items.insert(ALLOCITEM(addr,size,line)); glocal.sofar += size; glocal.total += size; if (glocal.maxalloc < glocal.sofar){ glocal.maxalloc = glocal.sofar; } glocal.nbmalloc++; }else if (strncmp(cmd,"realloc",7)==0){ unsigned long addr,newaddr; int size; sscanf (cmd+7,"%8lx %8lx %d",&addr,&newaddr,&size); ALLOCITEM al(addr,0,""); set::iterator it = glocal.items.find(al); if (it != glocal.items.end()){ glocal.sofar -= it->size; glocal.sofar += size; glocal.items.erase(it); glocal.items.insert(ALLOCITEM(newaddr,size,line)); }else if (glocal.invalid){ glocal.items.insert(ALLOCITEM(newaddr,size,line)); printf ("%s\n",line); } }else if (strncmp(cmd,"free",4)==0){ unsigned long addr; sscanf (cmd+4,"%8lx",&addr); ALLOCITEM al(addr,0,""); set::iterator it = glocal.items.find(al); if (it != glocal.items.end()){ glocal.sofar -= it->size; glocal.items.erase(it); }else if (glocal.invalid){ printf ("%s\n",line); } } return 0; unsigned long leak = 0; for (set::iterator it=glocal.items.begin(); it!=glocal.items.end(); it++){ leak += it->size; if (glocal.report) printf ("%s\n",it->line.c_str()); } if (glocal.stats){ printf ("Allocations : %lu\n",glocal.nbmalloc); printf ("Peak usage : %lu\n",glocal.maxalloc); printf ("Total allocation: %lu\n",glocal.total); printf ("Leaks : %d\n",glocal.items.size()); printf ("Leaks size : %lu\n",leak); } } return ret; return ret; }