问题描述
我在运行 C++ 应用程序时遇到 seg 错误.在 gdb 中,它以某种方式显示我的一个指针位置已损坏.但是我在我的应用程序中创建了 10 万个这样的对象指针.我怎样才能看到导致崩溃的一个我可以在 bt 命令中执行任何操作来查看该指针的生命周期吗?
I am getting seg fault while running a c++ application. In gdb it shows somehow my one pointer location getting corrupted. But I have 100 thousands of such object pointers created during my application. How can I watch one which is causing the crash Can I do any operation in bt command to see the lifetime of that pointer?
谢谢汝驰
推荐答案
过去我在大约 256K 指针的应用程序中遇到了一些内存泄漏问题(由编译器错误引起),所以我不得不以某种方式检查它.经过一番努力,我创建了一个包含所有已分配指针及其大小的表以及一些保持更新的函数.结果是这样的:
I had some mem-leaks problems in the past (caused by compiler bug) in apps with about 256K pointers so i had to check it somehow. After some struggle I created a table of all allocated pointers and their sizes and some functions to keep it updated. the result is this:
文件: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 this:
// 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
所以如果你包含 mmap.h 作为第一个包含!!!
So if you include mmap.h as a first include !!!
- 在函数 void mmap_err(const char* msg,DWORD ptr) 中放置断点
- 运行应用程序
- 如果发生任何分配错误,它将在异常之前中断,因此您可以实际查看信息和类型错误,并且还可以在发生错误的位置进行代码处理
我是 BDS2006 Turbo C++ 用户,所以如果我忘记了一些 VCL 内容,只需将其转换为 MSVC++ 或评论我,我会这样做,但我没有看到任何可能导致麻烦的东西.
I am BDS2006 Turbo C++ user so if I forgot some VCL stuff just convert it to MSVC++ or comment me and i will do it, but I don't see anything what could cause troubles.
PS.我发现对于我的编译器来说是一个致命错误:
PS. I found out that for my compiler is a fatal error to:
- 多次删除指针
- 具有没有适当构造函数/析构函数的结构
在这两种情况下都没有抛出异常,但内存管理器随后被损坏,因此分配错误,因此出现异常
in both cases no exception is thrown but memory manager is corrupted afterwards so it allocates wrongly hence exceptions
适合我的编译器的构造函数/析构函数
对于将动态分配的所有结构和类或其任何组件
是这样的:
Proper constructors/destructors for my compiler
for all structs and classes which will be dynamically allocated or any of their component
is 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; }
};
这篇关于回溯 C++ 代码 gdb 中的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!