1 现象:问题描述
在XXX产品转测试后,发现PS(Presence Server)在运行过程中发送NOTIFY消息时Coredown,导致服务中断,不能继续进行测试。
2 关键过程:根本原因分析
从运行现场获得core文件,然后使用gdb打开core文件后,得到的信息为:
#0 0x4d827811 in SipRequest::send() (this=0x8360480) at SipRequest.cpp:245
245 SipRequest.cpp: No such file or directory.
in SipRequest.cpp
(gdb) bt
#0 0x4d827811 in SipRequest::send() (this=0x8360480) at SipRequest.cpp:245
#1 0x4d7a7b8a in PS::CResourceListServer::sendListNotification() (this=0x4d367d80)
at src/ps/rls/CResourceListServer.cpp:2727
#2 0x4d686dec in MySipSession::onTimer(unsigned, unsigned, void*) (this=0x5046e780,
iTimerId=4590788, uUserTimerID=201, pData=0x0) at src/MySipSession.cpp:134
#3 0x4d69ceb0 in ConfSipService::onTimer(unsigned, unsigned, void*) (this=0x81e9780,
timerID=4590788, userTimerID=201, pData=0x5046e780) at src/PSService_ser.cpp:597
#4 0x43d5cee2 in CDistributedObjectBase::onTimer(unsigned, unsigned, void*) (this=0x81eb410,
timerID=4590788, userTimerID=201, pData=0x5046e780)
at /enip/d107/obj/mech_context/CDistributedObjectBase.cpp:509
#5 0x43d71138 in CDistributedObjectBaseMessageHandler::doHandleOnTimer(IScheduleMessage*) (
this=0x81eb4b8, pMsg=0x5047c408)
at /enip/d107/obj/mech_context/CDistributedObjectBaseMessageHandler.cpp:458
#6 0x43d70454 in CDistributedObjectBaseMessageHandler::handle(IScheduleMessage*) (this=0x81eb4b8,
pMsg=0x5047c408) at /enip/d107/obj/mech_context/CDistributedObjectBaseMessageHandler.cpp:124
#7 0x43d133f9 in CMessageHandlerBase::handle(IScheduleMessage*) (this=0x81d34c0, pMsg=0x5047c408)
at /enip/d107/obj/mech_sched/CMessageHandlerBase.cpp:112
#8 0x43d157c8 in CWorker::run() (this=0x4ac32008) at /enip/d107/obj/mech_sched/CWorker.cpp:454
#9 0x401234cf in startHook (arg=0x4ac32008) at /enip/d107/obj/common/Thread.cpp:612
#10 0x4002a020 in pthread_start_thread () from /lib/i686/libpthread.so.0
根据gdb打开core文件后得到的信息,可以定位出现问题的代码为:
this->getDialog()->m_pStackSession->doRequest(*requestMessage);
经过走读代码,发现关闭dialog的函数代码是这样写的:
void CloseRlsDialog()
{
this->m_pDialog->Close();
}
上面的代码在关闭dialog后,没有将值设置为NULL。
通过上面的分析,找到了问题的原因:
在运行过程中,dialog(SIP协议中的一种存放信息的上下文),一经被释放,但是下面的语句还在继续使用:this->getDialog()->m_pStackSession->doRequest(*requestMessage);此时this->getDialog()函数调用得到的信息是一个野指针,使用该野指针,就立即导致了程序Coredump。
3 结论:解决方案及效果
解决方案:
关闭dialog后将dialog指针赋值为NULL;
使用dialog之前判断指针是否为NULL;
效果:
问题得到了解决。
4 经验总结:预防措施和规范建议
在编写代码过程中,要求防止程序中出现野指针,更要防止野指针被使用。将无效的指针赋值为NULL,使用指针之前判断是否为NULL,可以有效防止野指针的使用。
5 备注
本问题出现在转测试阶段。
6 考核点
野指针的防止。
7 试题
防止程序中出现使用野指针的安全方法是:
(1)这种问题很难,没有办法防止;
(2)只要将无效的指针赋值为NULL即可;
(3)只要使用指针之前判断是否为NULL即可;
(4)当指针无效时将指针设置为NULL,使用指针之前判断指针是否为NULL。
答案:(4)
阅读(753) | 评论(0) | 转发(0) |