sql_varying的case语句导致nodejs因分段错误而崩溃。
void FBResult::clean_sqlda(XSQLDA *sqlda)
{
int i;
XSQLVAR* var;
for(i = 0, var= sqlda->sqlvar; i < sqlda->sqld;i++,var++)
{
switch(var->sqltype & ~1)
{
case SQL_ARRAY:
case SQL_BLOB: delete (ISC_QUAD*) var->sqldata; break;
case SQL_TIMESTAMP: delete (ISC_TIMESTAMP*) var->sqldata; break;
case SQL_TYPE_TIME: delete (ISC_TIME*) var->sqldata; break;
case SQL_TYPE_DATE: delete (ISC_DATE*) var->sqldata; break;
case SQL_TEXT:
case SQL_VARYING: delete [] var->sqldata; break;
case SQL_SHORT: delete (int16_t *) var->sqldata; break;
case SQL_LONG: delete (int32_t *) var->sqldata; break;
case SQL_INT64: delete (int64_t *) var->sqldata; break;
case SQL_FLOAT: delete (float *) var->sqldata; break;
case SQL_DOUBLE: delete (double *) var->sqldata; break;
default: return;
}
if(var->sqlind != 0) delete var->sqlind;
}
}
以下是如何为sql_varying分配sqldata:
case SQL_VARYING: var->sqldata = new char[var->sqllen + 3];
memset(var->sqldata, 0, 2);
memset(var->sqldata + 2, ' ', var->sqllen);
var->sqldata[var->sqllen + 2] = '\0';
break;
为什么clean_sqlda中的行会导致nodejs崩溃?如果我注释掉该行并重建扩展名,它就不会崩溃。该行假设清除为var-&gt; sqldata分配的内存。我该如何解决?
编辑:sql_text以这种方式分配:
case SQL_TEXT: var->sqldata = new char[var->sqllen + 1];
memset(var->sqldata, ' ', var->sqllen);
//memset(var->sqldata, 0, var->sqllen);
var->sqldata[var->sqllen] = '\0';
break;
但是我不认为我在任何地方使用sql_text(不确定)。
编辑#2: 经过进一步调试后,我确定该错误是由以下行引起的:
if(var->sqlind != 0) delete var->sqlind;
如果我将其替换为:
if(var->sqltype & 1) delete var->sqlind;
代码中的某处,sqlind的分配方式如下:
if(var->sqltype & 1){
var->sqlind = new short(-1);
}
用旧行替换旧行修复问题,nodejs不再崩溃。你是否认为旧行导致它崩溃,因为sqlind被分配给新的short(-1),这是一个null的标记我猜?
答案 0 :(得分:1)
该错误现已修复。 var-&gt; sqldata未初始化为0导致delete var-&gt; sqldata始终在空引用上运行,导致节点崩溃。
答案 1 :(得分:0)
您决定分配的是(var-> sqltype&amp; 1),而您决定免费是(var-> sqlind!= 0)。我会假设不匹配会崩溃,直到证明不是我是你。
可能的原因:var-&gt; sqlind未在不需要分配的代码路径中初始化。
答案 2 :(得分:0)
sqltype
最低有效位用于指示值是否为空。
如果已设置,则分配sqlind
,其值指示是否为null(值为-1表示null,0表示非null)。
因此,在分配或取消分配时测试该位的条件在两种情况下都应为(var->sqltype & 1)
。