Traceback pointer in c ++ gdb code

I get a seg error when running a C ++ application. In gdb, it somehow shows that my one pointer place is getting damaged. But I have 100 thousand such object pointers created during my application. How can I watch what causes a crash? Can I perform any operation on the bt command to see the lifetime of this pointer?

Thanks Ruci

+2
c ++ gdb
source share
2 answers

As far as I know, you cannot get such information using gdb, but for this purpose you can try valgrind memcheck with the option --track-originins

+1
source share

I had problems with mem leaks in the past (caused by a compiler error) in applications with landmarks of around 256 KB, so I had to check this somehow. After some struggle, I created a table of all the selected pointers, their sizes and some functions, in order to keep it updated. the result is the following:

File: mmap.h

//--------------------------------------------------------------------------- //--- Memory map system ver: 2.03 ------------------------------------------- //--------------------------------------------------------------------------- #ifndef _mmap_h #define _mmap_h //--------------------------------------------------------------------------- #define _mmap_aprox //--------------------------------------------------------------------------- /* new #ifdef _mmap_h if () mmap_new('Main',,sizeof()); #endif #ifdef _mmap_h if () mmap_del('Main',); #endif delete */ //--------------------------------------------------------------------------- struct _mmap_entry { char ids[4]; // id string DWORD beg,end; // mem adr <beg,end) _mmap_entry(){ beg=0; end=0; ((DWORD*)(ids))[0]='LLUN'; }; _mmap_entry(_mmap_entry& a) { *this=a; } ~_mmap_entry() {} _mmap_entry* operator = (const _mmap_entry *a) { *this=*a; return this; } //_mmap_entry* operator = (const _mmap_entry &a) { ...copy... return this; } }; //--------------------------------------------------------------------------- const int _mmap_entries=4*1024; // max num of allocated memory chunks (pointers) const int _mmapn_entries=32; // num of last news to remember const int _mmapd_entries=32; // num of last dels to remember static _mmap_entry mmap [_mmap_entries]; // memory map table active ptrs static _mmap_entry mmapn[_mmapn_entries]; // memory map table last news static _mmap_entry mmapd[_mmapd_entries]; // memory map table last dels static int mmaps=0; // num of used entries in memory map table static int mmapn_ix=0; // num of last deletes to remember static int mmapd_ix=0; // num of last deletes to remember static int mmap_errs=0; // error count static int mmap_news=0; // allocations count static int mmap_dels=0; // deallocations count //--------------------------------------------------------------------------- void mmap_err(const char* msg,DWORD ptr) // breakpointeable error { mmap_errs++; } //--------------------------------------------------------------------------- int mmap_new(DWORD ids,void* ptr,DWORD siz) // tracks all allocations return false if error { mmap_news++; int i,j; _mmap_entry e,*p; e.beg=DWORD(ptr); e.end=e.beg+siz; e.ids[0]=((char*)&ids)[3]; e.ids[1]=((char*)&ids)[2]; e.ids[2]=((char*)&ids)[1]; e.ids[3]=((char*)&ids)[0]; if (e.beg==0) { mmap_err("Not enough memory.",e.beg); return 0; } // find first i where mmap[i].end >= e.beg #ifdef _mmap_aprox if (!mmaps) i=0; else{ for (j=1;j<mmaps;j<<=1); j>>=1; if (!j) j=1; for (i=0;j;j>>=1) { i|=j; p=mmap+i; if ((i>=mmaps)||(e.beg<p->end)) i^=j; if ((e.beg<p->end)&&(e.end>p->beg)) { mmap_err("Bad allocation.",e.beg); // memory already allocated return 0; } } if (e.beg>=mmap[i].end) i++; } #endif #ifndef _mmap_aprox for (i=mmaps-1,p=mmap+i;i>=0;i--,p--) if (e.beg<p->end) { if (e.end>p->beg) { mmap_err("Bad allocation.",e.beg); // memory already allocated return 0; } } else break; i++; #endif // insert new pointer at i if (mmaps>=_mmap_entries) { mmap_err("Too many pointers.",e.beg); // _mmap_entries is too low return 0; } for (j=mmaps;j>i;j--) mmap[j]=mmap[j-1]; mmap[i]=e; mmaps++; // remember last new in mmapn table mmapn[mmapn_ix]=e; mmapn_ix++; if (mmapn_ix>=_mmapn_entries) mmapn_ix=0; return 1; }; //--------------------------------------------------------------------------- int mmap_del(DWORD ids,void* ptr) // tracks all deallocations return false if error { mmap_dels++; int i,j; _mmap_entry *p; DWORD adr=DWORD(ptr); if (adr==0) { mmap_err("Can not delete NULL.",adr); return 0; } if (mmap<=0) { mmap_err("Nothing to delete.",adr); return 0; } // find mmap[i] where beg==ptr and delete it if found #ifdef _mmap_aprox if (!mmaps) i=0; else{ for (j=1;j<mmaps;j<<=1); j>>=1; if (!j) j=1; for (i=0;j;j>>=1) { i|=j; p=mmap+i; if ((i>=mmaps)||(adr<p->beg)) i^=j; } if (adr==mmap[i].beg) { if (mmaps>1) for (j=i;j<mmaps-1;j++) mmap[j]=mmap[j+1]; mmaps--; // remember last delete in mmapd table mmapd[mmapd_ix]=mmap[mmaps]; mmapd_ix++; if (mmapd_ix>=_mmapd_entries) mmapd_ix=0; // delete ptr from mmap table mmap[mmaps].beg=0; mmap[mmaps].end=0; return 1; } for (p=mmap,j=0;j<=i;j++,p++) // test all mmap[j].beg < adr if (adr<p->end) // if overlap then ... { mmap_err("Wrong delete pointer.",adr); // pointer inside already allocated space return 0; } } #endif #ifndef _mmap_aprox for (p=mmap,i=0;i<mmaps;i++,p++) if (p->beg==adr) { if (mmaps>1) for (j=i;j<mmaps-1;j++) mmap[j]=mmap[j+1]; mmaps--; mmap[mmaps].beg=0; mmap[mmaps].end=0; return 1; } else if (p->beg>adr) break; for (p=mmap,i=0;i<mmaps;i++,p++) if ((adr>p->beg)&&(adr<p->end)) { mmap_err("Wrong delete pointer.",adr); // pointer inside already allocated space return 0; } #endif mmap_err("Delete pointer not found.",adr); return 0; }; //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- 

Now in your code just do the following:

 // edit the safe big enough number of pointers to use for your application in begin of the mmap.h _mmap_entries=512*1024; // before any delete/delete[] of pointer ptr add this: #ifdef _mmap_h if (ptr!=NULL) mmap_del('info',ptr); #endif if (ptr!=NULL) delete[] ptr; // after any new of pointer ptr of size siz [byte] add this: ptr=new BYTE[siz]; #ifdef _mmap_h if (ptr!=NULL) mmap_new('info',ptr,siz); #endif 

So, if you include mmap.h as the first enable !!!

  • place breakpoint inside function void mmap_err (const char * msg, DWORD ptr)
  • launch the application
  • If any distribution error occurs, it will be interrupted before the exception so that you can see the info and kind off error, and you can also execute the code where the error occurs.

I am a user of BBS2006 Turbo C ++, so if I forgot some VCL materials, just convert it to MSVC ++ or comment and I will do it, but I donโ€™t see anything that can cause problems.

PS. I found out that a fatal error occurred for my compiler:

  • delete pointer more than once
  • have structures without a proper constructor / destructor

in both cases, no exception is thrown, but the memory manager is subsequently corrupted, so it throws exceptions incorrectly.

The correct constructors / destructors for my compiler
for all structures and classes that will be dynamically distributed or any of their components
like this:

 class/struct T { public: T() {} T(T& a) { *this=a; } ~T() {} T* operator = (const T *a) { *this=*a; return this; } // if any dynamic allocation occur then this must be done also else not //T* operator = (const T &a) { ... copy a to this ... return this; } }; 
+1
source share

All Articles