Chinaunix首页 | 论坛 | 博客
  • 博客访问: 543076
  • 博文数量: 493
  • 博客积分: 2891
  • 博客等级: 少校
  • 技术积分: 4960
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 17:11
文章分类

全部博文(493)

文章存档

2010年(493)

分类:

2010-05-12 18:52:29

1 现象:问题描述
进行某版本的AIX移植工作。在功能测试时,使用的是server的DEBUG版本,即在编译时使用了-g选项,目的是在出现问题时方便调试。进入性能测试后,为了提高系统的性能,编译了release版本,去掉了-g选项,添加了-O选项。可是,当代码运行起来以后,却发现server模块经常发生core。
2 关键过程:根本原因分析
从栈顶可以看出,代码在执行strlen时发生了错误,应该是传给strlen的参数有问题。由于是release版本,无法看出参数的值,因此,只好继续向下观察堆栈。通过红色部分可以看出,是日志打印的代码调用了strlen,而该日志打印发生在EnableFRSession函数中。
观察EnableFRSession函数,找到所有的日志打印代码。好在不是很多,总共只有10处,可以挨个的进行检查。在检查中,发现了下面的可疑代码:
    SENDLOG_NEW((LVL_FINER, LOG_TYPE_SYSTEM, LOG_ACTION_VOID, FL,
                 DEF_SRV_MODULE_MANAGER, "One session is recoved!",
                 "SessionType [%d],SessionID[%s],MessageID[%s],MainState[%s],SubState[%s].",
                 rSrvSessWrapper->GetSessionType(),
                 rSrvSessWrapper->GetSessionID(),
                 rSrvSessWrapper->GetXMmsMessageID(),
                 g_pstrStateText[sessionMainState],
                 g_pstrSubstateText[sessionSubState]));
红色部分的代码将两个函数的返回值当作了参数,可是这两个函数的返回值都是string类型,而不是char *或者const char *。系统将临时的string对象当成了字符指针来处理,很可能会越界发生core。
3 结论:解决方案及效果
修改红色部分的代码,将string类型的指针传给SENDLOG:
    SENDLOG_NEW((LVL_FINER, LOG_TYPE_SYSTEM, LOG_ACTION_VOID, FL,
                 DEF_SRV_MODULE_MANAGER, "One session is recoved!",
                 "SessionType [%d],SessionID[%s],MessageID[%s],MainState[%s],SubState[%s].",
                 rSrvSessWrapper->GetSessionType(),
                 rSrvSessWrapper->GetSessionID().c_str(),
                 rSrvSessWrapper->GetXMmsMessageID().c_str(),
                 g_pstrStateText[sessionMainState],
                 g_pstrSubstateText[sessionSubState]));
经过测试,故障消失。
4 经验总结:预防措施和规范建议
1.     调用使用了可变参数的函数,一定要仔细检查传入的实参类型是否正确。
2.     注意string类型和char *的区别。
5 备注
这个问题很简单,解决起来也不费什么事。但还是有一点疑问:为什么编译器没有能够察觉上述的类型不匹配呢?C++可是一个强类型语言啊。
仔细观察sendlog的定义:
阅读(335) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~