SQlite C API вызывает ошибку сегментации приложения - PullRequest
1 голос
/ 06 августа 2020

Я оцениваю использование SQLite3 базы данных для приложения, которому необходимо записывать данные журнала. Случайно, почему я не могу воспроизвести проблему, я сталкиваюсь с app cra sh с ошибкой сегментации. Мне удалось создать дамп SEGV , который показывает следующие 2 трассировки:

1) sqlite3ExprListDup Trace

ip 0x7fff797b5b5d: _sigtramp+0x1d
ip 0x7fff787b11d7: sqlite3ExprListDup+0x127
ip 0x7fff787b5e62: sqlite3SelectDup+0x132
ip 0x7fff787848af: selectExpander+0x4df
ip 0x7fff787842f1: sqlite3WalkSelect+0x31
ip 0x7fff7885a87a: sqlite3SelectPrep+0x8a
ip 0x7fff7877a7be: sqlite3Select+0x28e
ip 0x7fff7874e28a: yy_reduce+0x10ca
ip 0x7fff7874b658: sqlite3RunParser+0x218
ip 0x7fff78749d0a: sqlite3LockAndPrepare+0x48a
ip 0x7fff787d61e7: sqlite3_prepare_v2+0xf7
ip 0x10ac75422: Connector::sqlite3Driver::executeDQL(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)+0x82

2) sqlite3WhereBegin Trace

ip 0x7fff69eb5b5d: _sigtramp+0x1d
ip 0x7fff68e8b804: sqlite3WhereBegin+0x1424
ip 0x7fff68e7da0f: sqlite3Select+0x34df
ip 0x7fff68f6010f: multiSelectOrderBy+0xcef
ip 0x7fff68e7d24e: sqlite3Select+0x2d1e
ip 0x7fff68e7caaa: sqlite3Select+0x257a
ip 0x7fff68e4e28a: yy_reduce+0x10ca
ip 0x7fff68e4b658: sqlite3RunParser+0x218
ip 0x7fff68e49d0a: sqlite3LockAndPrepare+0x48a
ip 0x7fff68ed61e7: sqlite3_prepare_v2+0xf7
ip 0x100996432: Connector::sqlite3Driver::executeDQL(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)+0x82

Первая трассировка встречается в операторах INSERT в таблице, содержащей 6 столбцов. Я нашел в Интернете похожие случаи (Firefox), возникшие из-за ошибки до SQlite version 3.18.x, которая была исправлена, начиная с этой версии. Вторая трассировка происходит в операторе SELECT из той же таблицы.

Среда C++11 на MacOSX с sqlite-3.22.0 C API.

База данных журнала - это одна структура таблицы, которая имеет следующий вид DDL:

CREATE TABLE IF NOT EXISTS log (uuid TEXT NOT NULL
                                sourcename TEXT NOT NULL,
                                sourceipaddress TEXT NOT NULL,
                                stimestamp TEXT NOT NULL,
                                qtimestamp TEXT NOT NULL,
                                severity INTEGER NOT NULL,
                                content TEXT NOT NULL);
CREATE INDEX IF NOT EXISTS idx_uuid ON log (uuid);
CREATE INDEX IF NOT EXISTS idx_stimestamp ON log (stimestamp);
CREATE INDEX IF NOT EXISTS idx_qtimestamp ON log (qtimestamp);
CREATE INDEX IF NOT EXISTS idx_severity ON log (severity);

При вставке данных в таблицу журнала приложение выполняет INSERT операторы по лотам (50 строк) с использованием оболочки и обеспечивает TRANSACTION BEGIN и COMMIT / ROLLBACK :

[public] const bool Connector::open(const std::string& dbName, sqlite3 *dbConnection) {
    int      connStatus   = sqlite3_open("log.db", &dbConnection);

    if (connStatus == SQLITE_OK) {
        return true;
        ... //Wrapper maintains the connection to the SQLite database
    }
    else {
        return false;
    }
}
[public] const bool Connector::startTransac() {
    ...
}
[public] const bool Connector::commitTransac() {
    ...
}
[public] const bool Connector::rollbackTransac() {
    ...
}
[public] const int Connector::executeDQL(const std::string& queryStmt) {
    if (queryStmt.find("SELECT ") >= 0) {
        sqlite3_stmt    *statement    = nullptr;
        int              sqLiteResult = sqlite3_prepare_v2(dbConnection, queryStmt.c_str(), -1, &statement, NULL);
    
        if (sqLiteResult == SQLITE_OK) {
            sqLiteResult = sqlite3_step(statement);
            sqLiteResult = sqlite3_finalize(statement);
        }
    
        return sqLiteResult;
    }
    else {
        return this->executeDML(queryStmt);
    }
}
[public] const int Connector::executeDML(const std::string& queryStmt) {
    char    *errorMsg = 0;
    int      sqLiteResult = sqlite3_exec(dbConnection, queryStmt.c_str(), nullptr, nullptr, &_errorMessage);
    
    if (sqLiteResult == SQLITE_OK) {
        sqLiteResult = sqlite3_changes(dbConnection);
    }
    
    return sqLiteResult
}

Кто-нибудь испытал то же самое и нашел решение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...