1 现象:问题描述
产品A在第一轮测试接近尾声时偶然发现XXX模块core,提供core文件和操作日志。产品A运行环境是solaris平台。
2 关键过程:根本原因分析
通过psatck 查看core文件的堆栈,发现接近栈顶处有如下可疑点(红色标示):
......
f9f31ed8 int I2000pm::PQXmlReader::GetPerfQueryitemExtendInfo(const int,const std::basic_string,std::allocator >&,const std::basic_string,std::allocator >&,I2000pm::SPerfQueryItemExtendInfo&) (0, 22c5, f4807868, f4807860, f48077c8, 0) + 1b0
f9f3ca50 int I2000pm::CinfoXPQTaskMOItem::InitOtherTaskMOItemPara() (9f6948, 9f6a10, f4807af0, f9fdc737, 7bd, 0) + 168
......
I2000pm::PQXmlReader::GetPerfQueryitemExtendInfo 函数调用时,this指针为 0 ?!。
通过 dbx 定位到相应代码:
int CinfoXPQTaskMOItem::InitOtherTaskMOItemPara()
{
…..
nResult = m_PQXmlReader->GetPerfQueryitemExtendInfo(
m_nDevType,strVersion,strMU, m_PerfQueryItemExtendInfo);
……
}
查看 m_PQXmlReader 值为 0;由此可以初步断定 m_PQXmlReader 变量的管理出现问题。
经过检视 m_PQXmlReader 相关管理代码发现:
1) m_PQXmlReader 是 类 CinfoXPQTaskMOItem的静态指针成员变量;在XXX模块初始化时进行了相应正确初始化
2) 在 类 CinfoXPQTaskMOItem 非静态方法 Clear 中对 m_PQXmlReader 进行清理释放
void CinfoXPQTaskMOItem::Clear()
{
......
m_PQXmlReader->destroy();
m_PQXmlReader = 0;
......
}
3) 在类 CinfoXPQTaskMOItem 析构函数中调用 Clear 方法
CinfoXPQTaskMOItem::~CinfoXPQTaskMOItem()
{
......;
Clear();
......
}
由上述分析,找出了问题的真正原因:在XXX模块初始化时对 m_PQXmlReader 进行了正确初始化;当类 CinfoXPQTaskMOItem的一个对象被删除,而进行析构时,对m_PQXmlReader 进行了清理,并赋值为0;之后当另一个活动的CinfoXPQTaskMOItem对象调用CinfoXPQTaskMOItem::InitOtherTaskMOItemPara函数,该函数执行 nResult = m_PQXmlReader->GetPerfQueryitemExtendInfo(m_nDevType,strVersion,strMU, m_PerfQueryItemExtendInfo) 时,m_PQXmlReader已经为0,所以产生core。
经过日志分析:证明确实存在上述操作过程。
根据上述分析过程操作相应版本,产生相同的core。此为必core问题
3 结论:解决方案及效果
解决方案:
1)类 CinfoXPQTaskMOItem 增加一个静态成员函数 Exit ,如下:
int CinfoXPQTaskMOItem::Exit( )
{
......
m_PQXmlReader->destroy();
m_PQXmlReader = 0;
......
}
2)在 XXX模块退出时,在其finalize函数种调用类 CinfoXPQTaskMOItem 静态成员函数 Exit;对m_PQXmlReader 进行清理和释放。
3)去掉在类 CinfoXPQTaskMOItem 非静态方法 Clear 中对 m_PQXmlReader 进行清理释放
效果:
按照上面的方案修改后,再次根据上述分析过程操作相应版本,没有产生core。问题得到解决。
4 经验总结:预防措施和规范建议
类静态指针成员变量清理释放的一般原则:
1) 定义一个类静态函数,在其中进行清理释放;
2) 不要在类非静态函数中,对类静态成员变量进行清理释放
3) 不要在析构函数中,对类静态成员变量进行清理释放
5 备注
本问题出现在转测试阶段。
6 考核点
类静态成员变量清理释放原则。
7 试题
关于类静态指针成员变量清理释放的一般原则,如下那些说法是正确的():
(1)在类析构函数中进行清理释放;
(2)定义一个类非静态函数,在其中进行清理释放;
(3)定义一个类静态函数,在其中进行清理释放;
答案:(3)
阅读(603) | 评论(0) | 转发(0) |