1 现象:问题描述
深圳scp7的10个SCF进程在10分钟内全部重启,并产生core文件
2 关键过程:根本原因分析
SCF进程core dump时产生了core文件,分析core文件,进程在core dump时,堆栈信息如下:
#2 0xe25f1d1c in TSyntaxTree::~TSyntaxTree (this=0x4ae0b7f8) at syntaxtree.C:44
#3 0xe25f1cb0 in TSyntaxTree::~TSyntaxTree (this=0x4ae0b858) at syntaxtree.C:41
#4 0xe25f1cb0 in TSyntaxTree::~TSyntaxTree (this=0x4ae0b798) at syntaxtree.C:41
#5 0xe25f1cb0 in TSyntaxTree::~TSyntaxTree (this=0x4ae0b930) at syntaxtree.C:41
#6 0xe25f1cb0 in TSyntaxTree::~TSyntaxTree (this=0x4ae0b360) at syntaxtree.C:41
#7 0xe25f1cf8 in TSyntaxTree::~TSyntaxTree (this=0x4ae0aac0) at syntaxtree.C:43
#8 0xe25f1cb0 in TSyntaxTree::~TSyntaxTree (this=0x4ae0a3d0) at syntaxtree.C:41
#9 0xe25f1cf8 in TSyntaxTree::~TSyntaxTree (this=0x4ae04c48) at syntaxtree.C:43
#10 0xe25f1cf8 in TSyntaxTree::~TSyntaxTree (this=0x4adffb30) at syntaxtree.C:43
#11 0xe25f1cf8 in TSyntaxTree::~TSyntaxTree (this=0x4adee2c0) at syntaxtree.C:43
#12 0xe25f1cb0 in TSyntaxTree::~TSyntaxTree (this=0x4adee0f8) at syntaxtree.C:41
初步定位为动态语音短信生成dll在析构语法树,即释放指针空间时出现异常。分析构造语法树及解析语音参数代码,针对性的对上述指针的赋值语句进行分析。
在如下代码中中找到如下赋值语句:
int IUserCreateSms()
{
…
//用数组存储参数
TParam pParam[MAX_PARAM_CNT];
…
if( Failure == pSynTree->explain(pParam, sSmsContent) )
{
*pRetSmsCnt = 0;
return 0;
}
其中:
1 TParam定义为:
//用数组存储参数
TParam pParam[MAX_PARAM_CNT];
struct TParam
{
char m_szName[MAX_PARAM_LEN+1];
TParValue m_uValue;
TExpType m_eType;
};
struct TParValue
{
char pValue[MAX_VALUE_LEN+1];
int iValue;
TParValue();
~TParValue();
};
2 explain ()函数为:
TBool TSyntaxTree::explain (TParam *pParam)
{
…
int iTmp = searchVar(pParam,pTmpSrc);
//如果找到变量参数
if( iTmp >= 0 )
{
if( pTmpSrc[0] == 'i' )
{
m_uResult.iVal = pParam[iTmp].m_uValue.iValue;
}
else if( pTmpSrc[0] == 's' )
{
m_uResult.pVal = pParam[iTmp].m_uValue.pValue;
}
}
m_uResult.pVal指向了函数局部变量的地址,在调用IUserCreatePrompt函数结束后,会释放pParam及其对应的地址空间。因此m_uResult.pVal就引用了一个已经被释放的地址空间。
在修改了语音配置文件,且修改时间间隔在5分钟及以上时,语音动态库会析构以前的语法树,重新生成新的语法树。在析构释放语法树过程中必然会释放m_uResult.pVal地址空间,由于m_uResult.pVal地址空间已经被释放,再次释放必然导致进程出现异常。
3 结论:解决方案及效果
动态库代码中引用了临时数组地址空间,存在重复释放指针及释放不属于自己的存储空间的问题。
对代码中m_uResult.pVal = pParam[iTmp].m_uValue.pValue;赋值部分进行修改,
给m_uResult.pVal临时分配属于自己的存储空间避免引用无效地址空间。
TBool TSyntaxTree::explain(TParam *pParam)
{
…
int iTmp = searchVar(pParam,pTmpSrc);
//如果找到变量参数
if( iTmp >= 0 )
{
if( pTmpSrc[0] == 'i' )
{
m_uResult.iVal = pParam[iTmp].m_uValue.iValue;
}
else if( pTmpSrc[0] == 's' )
{
if (NULL == strDuplicate(pParam[iTmp].m_uValue.pValue, m_uResult.pVal))
{
return Failure;
};
}
}
阅读(355) | 评论(0) | 转发(0) |