⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 195.txt

📁 SVM(支持向量机)和EM(最大熵)文本分类算法
💻 TXT
📖 第 1 页 / 共 5 页
字号:
语句时,主机复位。但是该语句似乎并无不妥。
再分析整个函数,pSpcCB在函数前部分已经被赋值,
pSpcCB = SpcCB + (PortTable+index)->spcNo;
但由于得到 index 后,没有任何判断,导致若MNT/MLT端口没有做半永久,端口激活后,

执行此部分函数,(PortTable+index)->spcNo 有可能为NULL_WORD,于是,运算后,pSpc

CB 可能为非法值。此时主机在取进行判断,就不知会导致什么后果了。
其实,改起来很简单,只要在这两句前增加一个判断就行了。于是,修改代码为:
if ( (PortTable+index)->spcNo != NULL_WORD)
{
	pSpcCB = SpcCB + (PortTable+index)->spcNo;
	if ( SPC_STATE_OK == pSpcCB->bySpcState )
	{。。。}
}
	修改后,问题不再重现。
经过分析可以发现,编译环境是有很大的容许空间的,若主机没有做充分的保护,很可能

会有极严重的随即故障出现。所以编程时一定要考虑各种可能情况;而测试中遇到此类死

机问题,则要耐心的定位到具体是执行哪句代码时出现的,再进行分析。因为问题很隐蔽

,直接分析海一样的代码是很难发现的。


4、变量类型定义错误
【案例1.4.1】
【正            文】
        在FRI板上建几条FRPVC,其DLCI类型分别为:10Bit/2bytes、10bit/3bytes、16

bit/3bytes、17bit/4bytes、23bit/4bytes。相应的DLCI值为:16、234、991、126975、

1234567,然后保存,重起MUX,观察PVC的恢复情况,结果DLCI值为16、234和991的PVC正

确恢复,而DLCI=126975的PVC恢复的数据错误为61439,而DLCI=1234567的PVC完全没有恢

复。
        对于17/4类型,DLCI=126975的PVC在恢复时变成61439,根据这条线索,查找原因

,发现126975-61439=65535,转化二进制就是10000000000000000,也就是说在数据恢复或

保存时把原数据的第一个1给忽略了。此时第一个想法是:在程序处理中,把无符号长整型

变量当作短整型变量处理了,为了证实这个判断,针对17bit/4bytes类型又重新设计测试

用例:(1) 先建PVC,DLCI=65535,然后保存,重起MUX,观察PVC的恢复情况,发现PVC

能够正确恢复;
(2)再建PVC,DLCI=65536,然后保存,重起MUX,观察PVC的恢复情况,此时PVC不能正确

恢复。
至此基本可以断定原因就是出在这里。带着这个目的查看原代码,发现在以下代码中有问

题:
int	_GetFrDlci( DWORD* dwDlci, char* str, DWORD dwDlciType, DWORD dwPortType, 

DWORD dwSlotID, DWORD dwPortID)
{          DWORD  tempDlci;
	char	szArg[80];
1	char	szLine[80];
	ID	LowPVCEP;
            DWORD	dwDlciVal[5][2] =
   		{ {16,1007}, {16,1007}, {1024,64511},
   		  {2048,129023}, {131072,4194303} } ;
            ...
}

typedef struct tagFrPppIntIWF
{
	...
	WORD	wHdlcPort;
	WORD	wHdlcDlci;      
	WORD	wPeerHdlcDlci;   
	WORD	wPeerOldAtmPort;
	...	
}	SFrPppIntIWFData;

DWORD 	SaveFrNetIntIWFData ( DWORD *pdwWritePoint )
{
	BYTE	bSlotID, bPeerSlotID;
	DWORD	dwCCID, dwPeerCCID;
	WORD	wHdlcPort, wAtmPort, wIci, wPeerIci, wPeerHdlcPort ;
	WORD	wCount;
            ...
}

DWORD 	SaveFrNetExtIWFData ( DWORD *pdwWritePoint )
{
	BYTE	bSlotID;
	DWORD	dwCCID, dwPeerCCID;
	WORD	wHdlcPort, wAtmPort, wIci ;
	WORD	wCount;
	...
unSevData.FrNetExtIWF[wCount].bSlotID	= bSlotID;
	unSevData.FrNetExtIWF[wCount].wHdlcPort	= wHdlcPort;
	unSevData.FrNetExtIWF[wCount].wHdlcDlci	= gFrPVCEP[bSlotID ][ gFrPVCC[bSlotID

][dwCCID].dwLoPVCEP ].dwDLCI;
	unSevData.FrNetExtIWF[wCount].wOldAtmPort	= wAtmPort;
	unSevData.FrNetExtIWF[wCount].wAtmDlci	= gFrPVCEP[ bSlotID ][ gFrPVCC[bSlotID

][dwCCID].dwHiPVCEP ].dwDLCI;
	unSevData.FrNetExtIWF[wCount].dwMapMode = gFrPVCC[bSlotID][dwCCID].dwMapMode;


     ...
       }


DWORD RestoreFrNetExtIWFData ( WORD wSlotID, BYTE *pReadPoint )
{
	WORD	wCount, wTotalNetIWF;
	BYTE	bSlotID, bHdlcDlciType, bAtmDlciType;
	WORD	wOldAtmPort, wAtmDlci, wHdlcPort, wHdlcDlci;  
	DWORD	dwMapMode, dwCIR, dwBe;
	DWORD	dwCCID, dwResult, dwAtmPort;
	wTotalNetIWF = g_MuxData.SevDataSize.wFrNetExtIWFNum;
	...
}

DWORD RestoreFrHdlcIntIWFData ( WORD wSlotID, BYTE *pReadPoint )
{
	WORD	wCount, wTotalHdlcIWF;
	DWORD	dwCCID, dwPeerCCID, dwAtmPort, dwPeerAtmPort;
	DWORD	dwResult;
	BYTE	bSlotID, bPeerSlotID;
	WORD	wHdlcPort, wOldAtmPort, wCIR;
	WORD	wPeerHdlcPort, wPeerOldAtmPort;
            ...
}

        其中涉及DLCI值的变量都为WORD(即无符号短整型)类型,在程序的处理时,出

现WORD和DWORD(无符号长整型)类型在一句中同时存在的情况,至此可以判断问题出在这

里。由于DLCI值在不同类型时的取值范围不同,前三种类型的取值范围为16~991,第四种

取值范围为2048~126975,第五种取值范围为131072~4194303,所以当采用前三种DLCI类型

时,采用WORD类型最大值为65535,已经完全够用了;而对于第四种类型时,其取值在超过

65535时,获取DLCI值的函数_GetFrDlci()采用DWORD类型,而负责保存和恢复的两个函

数SaveFrNetExtIWFData()和RestoreFrNetExtIWFData(),都把DLCI的值当作WORD类型

进行处理,因此导致DLCI取值越界,于是程序把原本为长整型的DLCI强制转换成整型,从

而导致DLCI值在恢复时,比原数据小65536。而在程序运行过程中,这些数据保存在DRAM中

,程序运行直接从DRAM中获取数据,程序不会出错;当FRI板复位或插拔后,需要从FLASH

中读取数据,此时恢复函数的错误就表现出来。
       另一个问题是为什么23/4类型的DLCI数据不能恢复?这是由于对于23/4类型的PVC

,其DLCI的取值范围为:131072~4194303,而程序强制转换并恢复的数据最大只能是6553

5,所以这条PVC不能恢复。
        至此,DLCI数据恢复出错的原因完全找到,解决的方法是将DLCI的类型改为DWOR

D类型。从这个案例可以看出,在程序开发中一个很低级的错误,将在实际工作中造成很严

重的后果。

【案例1.4.2】
【正            文】
        在FRI板上建几条FRPVC,其DLCI类型分别为:10Bit/2bytes、10bit/3bytes、16

bit/3bytes、17bit/4bytes、23bit/4bytes。相应的DLCI值为:16、234、991、126975、

1234567,然后保存,重起MUX,观察PVC的恢复情况,结果DLCI值为16、234和991的PVC正

确恢复,而DLCI=126975的PVC恢复的数据错误为61439,而DLCI=1234567的PVC完全没有恢

复。
        对于17/4类型,DLCI=126975的PVC在恢复时变成61439,根据这条线索,查找原因

,发现126975-61439=65535,转化二进制就是10000000000000000,也就是说在数据恢复或

保存时把原数据的第一个1给忽略了。此时第一个想法是:在程序处理中,把无符号长整型

变量当作短整型变量处理了,为了证实这个判断,针对17bit/4bytes类型又重新设计测试

用例:(1) 先建PVC,DLCI=65535,然后保存,重起MUX,观察PVC的恢复情况,发现PVC

能够正确恢复;
(2)再建PVC,DLCI=65536,然后保存,重起MUX,观察PVC的恢复情况,此时PVC不能正确

恢复。
至此基本可以断定原因就是出在这里。带着这个目的查看原代码,发现在以下代码中有问

题:
int	_GetFrDlci( DWORD* dwDlci, char* str, DWORD dwDlciType, DWORD dwPortType, 

DWORD dwSlotID, DWORD dwPortID)
{          DWORD  tempDlci;
	char	szArg[80];
	char	szLine[80];
	ID	LowPVCEP;
            DWORD	dwDlciVal[5][2] =
   		{ {16,1007}, {16,1007}, {1024,64511},
   		  {2048,129023}, {131072,4194303} } ;
            ...
}

typedef struct tagFrPppIntIWF
{
	...
	WORD	wHdlcPort;
	WORD	wHdlcDlci;      
	WORD	wPeerHdlcDlci;   
	WORD	wPeerOldAtmPort;
	...	
}	SFrPppIntIWFData;

DWORD 	SaveFrNetIntIWFData ( DWORD *pdwWritePoint )
{
	BYTE	bSlotID, bPeerSlotID;
	DWORD	dwCCID, dwPeerCCID;
	WORD	wHdlcPort, wAtmPort, wIci, wPeerIci, wPeerHdlcPort ;
	WORD	wCount;
            ...
}

DWORD 	SaveFrNetExtIWFData ( DWORD *pdwWritePoint )
{
	BYTE	bSlotID;
	DWORD	dwCCID, dwPeerCCID;
	WORD	wHdlcPort, wAtmPort, wIci ;
	WORD	wCount;
	...
unSevData.FrNetExtIWF[wCount].bSlotID	= bSlotID;
	unSevData.FrNetExtIWF[wCount].wHdlcPort	= wHdlcPort;
	unSevData.FrNetExtIWF[wCount].wHdlcDlci	= gFrPVCEP[bSlotID ][ gFrPVCC[bSlotID

][dwCCID].dwLoPVCEP ].dwDLCI;
	unSevData.FrNetExtIWF[wCount].wOldAtmPort	= wAtmPort;
	unSevData.FrNetExtIWF[wCount].wAtmDlci	= gFrPVCEP[ bSlotID ][ gFrPVCC[bSlotID

][dwCCID].dwHiPVCEP ].dwDLCI;
	unSevData.FrNetExtIWF[wCount].dwMapMode = gFrPVCC[bSlotID][dwCCID].dwMapMode;


     ...
       }


DWORD RestoreFrNetExtIWFData ( WORD wSlotID, BYTE *pReadPoint )
{
	WORD	wCount, wTotalNetIWF;
	BYTE	bSlotID, bHdlcDlciType, bAtmDlciType;
	WORD	wOldAtmPort, wAtmDlci, wHdlcPort, wHdlcDlci;  
	DWORD	dwMapMode, dwCIR, dwBe;
	DWORD	dwCCID, dwResult, dwAtmPort;
	wTotalNetIWF = g_MuxData.SevDataSize.wFrNetExtIWFNum;
	...
}

DWORD RestoreFrHdlcIntIWFData ( WORD wSlotID, BYTE *pReadPoint )
{
	WORD	wCount, wTotalHdlcIWF;
	DWORD	dwCCID, dwPeerCCID, dwAtmPort, dwPeerAtmPort;
	DWORD	dwResult;
	BYTE	bSlotID, bPeerSlotID;
	WORD	wHdlcPort, wOldAtmPort, wCIR;
	WORD	wPeerHdlcPort, wPeerOldAtmPort;
            ...
}

        其中涉及DLCI值的变量都为WORD(即无符号短整型)类型,在程序的处理时,出

现WORD和DWORD(无符号长整型)类型在一句中同时存在的情况,至此可以判断问题出在这

里。由于DLCI值在不同类型时的取值范围不同,前三种类型的取值范围为16~991,第四种

取值范围为2048~126975,第五种取值范围为131072~4194303,所以当采用前三种DLCI类型

时,采用WORD类型最大值为65535,已经完全够用了;而对于第四种类型时,其取值在超过

65535时,获取DLCI值的函数_GetFrDlci()采用DWORD类型,而负责保存和恢复的两个函

数SaveFrNetExtIWFData()和RestoreFrNetExtIWFData(),都把DLCI的值当作WORD类型

进行处理,因此导致DLCI取值越界,于是程序把原本为长整型的DLCI强制转换成整型,从

而导致DLCI值在恢复时,比原数据小65536。而在程序运行过程中,这些数据保存在DRAM中

,程序运行直接从DRAM中获取数据,程序不会出错;当FRI板复位或插拔后,需要从FLASH

中读取数据,此时恢复函数的错误就表现出来。
       另一个问题是为什么23/4类型的DLCI数据不能恢复?这是由于对于23/4类型的PVC

,其DLCI的取值范围为:131072~4194303,而程序强制转换并恢复的数据最大只能是6553

5,所以这条PVC不能恢复。
        至此,DLCI数据恢复出错的原因完全找到,解决的方法是将DLCI的类型改为DWOR

D类型。从这个案例可以看出,在程序开发中一个很低级的错误,将在实际工作中造成很严

重的后果。

5、正确使用逻辑与&&、屏蔽&操作符
【案例1.5.1】
【案例描述】:由于C语言中位与比求模效率高,因而系统设计时,对于模128的地方都改

为与127,系统定义的宏为#define MOD128  127和#define W_MOD    127(定义的宏的名字

易引起误解),但实际程序中还是采取求模,从而引起发送窗口欲重发的和实际重发的不一

致,最终导致链路复位此类严重问题,曾在定位此问题时花了不少时间。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -