为什么sqlite3_exec失败并带有回调中止症状?

时间:2017-07-12 09:38:36

标签: c sqlite

from sqlite docuementation

  

如果sqlite3_exec()回调返回非零,则sqlite3_exec()   例程返回SQLITE_ABORT而不再调用回调   不运行任何后续的SQL语句。

gdbing功能,其中出现中止信号,如下所示

function() {
 ... // valid sql, valid non-null database pointer
 rc = sqlite3_exec(database, sql, callback, 0, &err_msg);
 ... // address of where sqlite3-exec expected to return to, but SIGABRT returns
}

callback(arguments***) {
  ...//read arguments content
  return 0; //the only local return statement
}

奇怪的是,如果回调逻辑得到注释,除了返回语句代码在没有SIGABRT的情况下工作,这意味着内容中的错误,但gdbing回调函数在最后一个return语句之前没有任何错误!

编辑

回调

int readTable(void *pt, int argc, char **argv, char **colName)
{
  if(table == NULL) {
    table = calloc(1, sizeof(Table));
    table->ncol = argc;
    table->colname = malloc(argc*sizeof(String));
    table->coltype = malloc(argc*sizeof(int));
    for(int i = 0; i < argc; i++) {
      table->colname[i] = colName[i];
      table->coltype[i] = getDataType(colName[i]);
    }
    table->row = malloc(sizeof(Row));
    table->current = table->row;
    table->row->val = malloc(argc*sizeof(String));
  }
  else {
    table->current->nxt = malloc(sizeof(Row));
    table->current->nxt->val = malloc(argc*sizeof(String));
    table->current = table->current->nxt;
  }

  for(int i = 0; i < argc; i++) {
    if(!argv[i])
      continue;
    table->current->val[i] = malloc(strlen(argv[i]));
    strcpy(table->current->val[i], (const char*) argv[i]);
  }

  table->size++;
  return 0; //otherwise gets aborted
}

中止信号在sqlite3_exec时返回,而不是在回调执行时,核心转储。

根据下面的@Ctx评论,我混合SIGABRT和SQLITE_ABORT(假设它返回中止信号,但它没有)。什么是中止信号返回,而sqlite3_exec执行

1 个答案:

答案 0 :(得分:0)

问题与sqlite3没有直接关系,但与回调实现有关。

根据@Ctx评论,我在SIGABRT和SQLITE_ABORT之间混合,两者都没有对彼此产生影响,SIGABRT在回调中返回,因为一个未初始化的内存使用导致内存损坏。

table->current->val[i] = malloc(strlen(argv[i]));
strcpy(table->current->val[i], (const char*) argv[i]);

必须更改为

table->current->val[i] = malloc(strlen(argv[i])+1);
strcpy(table->current->val[i], (const char*) argv[i]);
//or
table->current->val[i] = strdup(argv[i]);

同样的问题上面的回调片段实际上是垃圾,它还有其他与内存损坏无关的错误。