案例 1
在一次测试中,并没有记得做了什么操作,发现HONET系统的主机复位了,之后,系统又工作正常了。由于没有打开后台的跟踪窗口,当时查了半天没有眉目。过了半天,现象又出现了,而且这次是主机在反复复位,系统根本无法正常工作了。
我凭记忆,判断应该是与当时正在测试的DSL板的端口配置有关。于是将板上所有端口配置为普通2B+D端口,重新加载在主机数据,现象消失。于是初步定位为主机在DSL端口处理过程中有重大错误。
我在新的数据上努力恢复原出问题的现象,却一直没有重现,于是恢复原数据,加载后立即重现。并注意到,当DSL端口激活时,主机复位。仔细比较两种数据的差别,发现出现主机复位问题的数据中DSL板配置了MNT/MLT端口,但是没有做DSL端口之间的半永久数据。
于是在程序中不断加打印语句,通过后台的DBWIN调试程序跟踪,最后终于定位为:每当执行到portdsl.c的DeviceDslMsgProc()函数中处理U口透传的
if ( SPC_STATE_OK == pSpcCB->bySpcState )
语句时,主机复位。但是该语句似乎并无不妥。
再分析整个函数,pSpcCB在函数前部分已经被赋值,
pSpcCB = SpcCB + (PortTable+index)->spcNo;
但由于得到 index 后,没有任何判断,导致若MNT/MLT端口没有做半永久,端口激活后,执行此部分函数,(PortTable+index)->spcNo 有可能为NULL_WORD,于是,运算后,pSpcCB 可能为非法值。此时主机在取进行判断,就不知会导致什么后果了。
其实,改起来很简单,只要在这两句前增加一个判断就行了。于是,修改代码为:
if ( (PortTable+index)->spcNo != NULL_WORD)
{
pSpcCB = SpcCB + (PortTable+index)->spcNo;
if ( SPC_STATE_OK == pSpcCB->bySpcState )
{。。。}
}
修改后,问题不再重现。
经过分析可以发现,编译环境是有很大的容许空间的,若主机没有做充分的保护,很可能会有极严重的随即故障出现。所以编程时一定要考虑各种可能情况;而测试中遇到此类死机问题,则要耐心的定位到具体是执行哪句代码时出现的,再进行分析。因为问题很隐蔽,直接分析海一样的代码是很难发现的。