SQLite中出现分段错误

Segmentation fault in SQLite

本文关键字:分段 错误 SQLite      更新时间:2023-10-16

我的DataBase.cpp文件中的代码:

#include "DataBase.h"
#include <sqlite3.h>
#include <string.h>
#include <wx/msgdlg.h>
bool CanClose(void)
{
    sqlite3 *Sqlite;
    sqlite3_stmt *sqlstmt;
    char *result;
    if(sqlite3_open("SysConfig",&Sqlite)==SQLITE_OK)
    {
       sqlite3_prepare(Sqlite,"SELECT config_value FROM configuration WHERE config_id = 1;",-1,&sqlstmt,NULL);
       sqlite3_step(sqlstmt);
       result = (char*)sqlite3_column_text(sqlstmt,0);
       sqlite3_close(Sqlite);
       if(strcmp(result,"YES")==1)    //Error Here
           return true;
       else
           return false;
    }
    else
    {
        wxMessageBox(_("Cannot Find System File!"),_("Error!"));
        sqlite3_close(Sqlite);
        return false;
    }
}

我的程序突然运行…当我尝试调试它时,上面指示的行(第19行)给出了一些错误,如:

程序收到信号SIGSEGV, Segmentation fault.

进一步反汇编语句显示汇编指令出错

call 0x80500b0

知道代码有什么问题吗?

段故障原因

sqlite3_column_text的sqlite3文档说:

如果这些例程被调用[…]在sqlite3_step()返回SQLITE_ROW以外的东西后,结果是未定义的。"

您没有检查sqlite3_step的返回值,因此似乎您的查询返回某种错误,然后sqlite3_column_text返回无效指针。

调试SQL错误

根据prepare的文档:

建议所有新程序使用sqlite3_prepare_v2()sqlite3_prepare16_v2()接口。为了向后兼容,保留了两个较旧的接口[包括您调用的sqlite3_prepare],但不鼓励使用它们。

[…]

发生错误时,sqlite3_step()将返回详细错误码或扩展错误码之一。遗留的行为是,sqlite3_step()将只返回一个通用的SQLITE_ERROR结果代码,应用程序将不得不再次调用sqlite3_reset(),以便找到问题的潜在原因。使用"v2"准备接口,立即返回错误的潜在原因。

所以如果你切换到新的接口,它应该给出一个更有信息量的消息,而不是通用的SQLITE_ERROR

您也可以尝试使用sqlite3命令行程序,它将直接告诉您错误是什么。示例会话:

user@host:/path$ sqlite3 test.sqlite
sqlite> create table example ( id numeric primary key );
sqlite> select bogus from example;
Error: no such column: bogus

顺便说一下,对于标准c++, #include <string.h>使用#include <cstring>, bool CanClose(void)使用bool CanClose()