1 现象:问题描述
在Server和ChargingServer日志中发现同一个接收方号码(如13900000002),既在成功接收方列表中,又在失败接收方列表中。
2 关键过程:根本原因分析
根据现象分析,造成这一问题,可能的原因有三点:一是,传入系统的地址值被错误修改;二是,传入系统的地址值正确,但分析号码时出错,导致生成的成功/失败接收方列表错误;三是,分析号码正确,但在后续处理中(向ChargingServer发消息前)出错。
采用从出错点向前追溯的方法查找定位。考虑到消息打印一般不会修改消息的内容(如本案例中的成功/失败接收方列表的值),故由发送消息的发送机制向前追溯。
考虑到向ChargingServer发送CMM2CSKeyPointProcessReq消息的时候,Server调用发送机制的CSrvSendMech::SendMessage()方法。通过在代码中增加日志打印,发现SendMessage()方法中,在调用RegisterSendUnit()之前,CMM2CSKeyPointProcessReq消息的FailedRecipientList, SuccessRecipientList是正确的,而调用了RegisterSendUnit()之后,FailedRecipientList, SuccessRecipientList便出错了。因此,可以基本确定造成成功/失败列表错误的原因是上面分析的原因三,并且导致出错的函数是RegisterSendUnit()。
进一步跟踪代码,发现RegisterSendUnit()中有如下一段代码:
if ((MMS_UINT32)EN_MSG_SRV_CHARGE_KEY_POINT_REQ == pMsg->GetMsgType())
{
CMM2CSKeyPointProcessReq* pMM2CSKeyPointProcessReq = (CMM2CSKeyPointProcessReq *)pMsg;
std::list& pReceiver = pMM2CSKeyPointProcessReq->GetlistXMmsSuccessRecipientList();
std::list::iterator Iter = pReceiver.begin();
if (pReceiver.end() != Iter)
{
…
}
else
{
pReceiver = pMM2CSKeyPointProcessReq->GetlistXMmsFailedRecipientsList();
Iter = pReceiver.begin();
…
}
}
注意代码中红色字体部分,函数中首先定义了一个引用std::list& pReceiver并为其初始化为pMM2CSKeyPointProcessReq->GetlistXMmsSuccessRecipientList(),即pReceiver指向成功接收方列表。如果成功接收方列表为空,则在函数的后半部分又对pReceiver进行了一次赋值:
pReceiver = pMM2CSKeyPointProcessReq->GetlistXMmsFailedRecipientsList();。
作者原意是想让pReceiver先指向成功接收方列表(SuccessRecipientList),对成功列表作了一些判断操作后,再让pReceiver指向失败接收方列表(FailedRecipientsList),对失败接收方列表进行操作。
但是,这里使用的pReceiver的类型是引用类型。在C++中,引用被初始化后,对引用进行的所有操作实际上都作用在它所指向的对象上。因此,这里对pReceiver进行第二次赋值的时候,实际上是将pReceiver所指向的SuccessRecipientList的值作了更改,所以第二次赋值的效果是将失败接收方列表(FailedRecipientsList)赋给了成功接收方列表(SuccessRecipientList),最终导致SuccessRecipientList和FailedRecipientsList的内容相同,且均为号码分析失败的接收方地址,即问题单NYGD06530中的错误。
3 结论:解决方案及效果
我们可通过将pReceiver定义为指针类型来实现作者的意图,对代码修改如下:
if ((MMS_UINT32)EN_MSG_SRV_CHARGE_KEY_POINT_REQ == pMsg->GetMsgType())
{
CMM2CSKeyPointProcessReq* pMM2CSKeyPointProcessReq = (CMM2CSKeyPointProcessReq *)pMsg;
std::list* pReceiver =&(pMM2CSKeyPointProcessReq->GetlistXMmsSuccessRecipientList(;
std::list::iterator Iter = pReceiver->begin();
if (pReceiver->end() != Iter)
{
…
}
else
{
pReceiver = & (pMM2CSKeyPointProcessReq->GetlistXMmsFailedRecipientsList());
Iter = pReceiver->begin();
…
}
}
阅读(309) | 评论(0) | 转发(0) |