为什么这个崩溃nodejs

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; } } 

以下是sqldata是如何分配给sql_varying的:

  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崩溃? 如果我注释掉这条线并重build扩展,它不会崩溃。 该行假设清除分配给var-> 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:进一步debugging后,我确定错误是由行:

 if(var->sqlind != 0) delete var->sqlind; 

如果我将其replace为:

 if(var->sqltype & 1) delete var->sqlind; 

在代码的某处,sqlind是这样分配的:

  if(var->sqltype & 1){ var->sqlind = new short(-1); } 

用新行replace旧行修复问题和nodejs不再崩溃。 你认为旧的行导致它崩溃,因为sqlind被分配给新的short(-1),这是一个空标记我猜?

该错误现在已修复。 var-> sqldata未初始化为0,导致删除var-> sqldata始终运行,即使在空引用导致节点崩溃。

你决定分配的是(var-> sqltype&1),而你决定释放(var-> sqlind!= 0)。 如果我是你,我会认为这个不匹配会崩溃。

可能的进一步原因:var-> sqlind没有在不需要分配的代码path中初始化。

sqltype最低有效位用于指示值是否可以为空。
如果它被设置, sqlind被分配,并且它的值指示它是否空(值-1为空,0为非空值)。

所以当你分配它或者释放它的时候,testing这个位的条件应该是(var->sqltype & 1)