有没有这样的经历,程序崩溃或者running abnormal, 经过一番调查,发现是某个变量被意外的改动了,但是到底是什么地方意外修改了我的数据呢?一般我们可以采用2分法逐步缩小怀疑对象的范围,可问题是很多“坏人”不是那么容易发现的。比如你看:
class arrowpig
{
private:
char* m_pText;
std::list<char*> m_dataList;
public:
~arrowpig()
{
for(std::list<char*>::iterator iter=m_dataList.begin();iter!=m_dataList.end();iter++)
{
delete (*iter);
}
}
};
#include <ThirdPartyLib.h> //我们的程序用了第三方的库
arrowpig inst;
……
ThirdPartyLib::someClass 3rdInst(para1,para2,para3);
我发现只要一执行ThirdPartyLib::someClass 的构造函数,arrowpig实例inst的内容就被修改了,于是造成inst析构时crash! 这个时候比较适合在GDB中使用watch命令:
gdb> watch inst.m_pText
这样,每当inst.m_pText中的内容被改动(读或者写)的时候,程序都会停下来,然后用where命令就能比较方便的定位罪魁祸首。但是注意一点,使用watch以后,程序会运行得非常的慢,所以实际操作的时候一定先要大致确认怀疑对象,在即将执行你怀疑的代码之前设置断点,然后使用watch,目的是减少受watch影响的范围。
上面这个问题最后发现是 由于我们include的第三方库的头文件版本和实际link的库文件版本不一致。
头文件告诉我们ThirdPartyLib::someClass 占用100字节,但是库的实现文件认为是120个字节,于是在构造函数中修改了后面的20个字节,破坏了同样在栈中的属于arrowpig实例的内容。