加载自定义sqlite fts5扩展程序时如何调试错误?

时间:2019-07-20 06:34:18

标签: sqlite

为sqlite3全文引擎(fts5)编写了自定义排名功能。尝试使用“ .load /var/www/rankprice.so”加载该扩展时,该扩展会编译,但会引发“分段错误(核心已转储)sqlite3”错误。不确定我的扩展代码的正确性。

我已经用文档中的代码替换了原来的排名功能。扩展加载代码也从文档中复制而来。

这是3个功能:     static void rankprice(//实际扩展功能,     fts5_api * fts5_api_from_db(sqlite3 * db)//获取指向fts5_api指针的指针     int sqlite3_extension_init //加载扩展名

文档尚未在https://www.sqlite.org/fts5.html#extending_fts5上更新。在功能

fts5_api *fts5_api_from_db(sqlite3 *db){
    fts5_api *pRet = 0;
    sqlite3_stmt *pStmt = 0;
    if( SQLITE_OK==sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0) ){
        sqlite3_bind_pointer(pStmt, (void*)&pRet, "fts5_api_ptr", NULL);
        sqlite3_step(pStmt);
    }
    sqlite3_finalize(pStmt);
    return pRet;
}

sqlite3_bind_pointer应该有5个参数,第二个参数应该是一个int,但是我不确定它的正确值。

这是完整的代码:

    #include <stdio.h>
    #include <assert.h>
    #include "sqlite3ext.h"
    SQLITE_EXTENSION_INIT1

    /*
    ** Actual extension function, copied  from https://www.sqlite.org/fts5.html
    */
    static void rankprice(
        const Fts5ExtensionApi *pApi,
        Fts5Context *pFts,
        sqlite3_context *pCtx,
        int nVal,
        sqlite3_value **apVal
    ){
          int rc;
          int nToken;
          rc = pApi->xColumnSize(pFts, -1, &nToken);
          if( rc==SQLITE_OK ){
            sqlite3_result_int(pCtx, nToken);
          }else{
            sqlite3_result_error_code(pCtx, rc);
          }
    }

    /*
    ** Return a pointer to the fts5_api pointer for database connection db.
    ** If an error occurs, return NULL and leave an error in the database
    ** handle (accessible using sqlite3_errcode()/errmsg()).
    */
        fts5_api *fts5_api_from_db(sqlite3 *db){
            fts5_api *pRet = 0;
            sqlite3_stmt *pStmt = 0;
            if( SQLITE_OK==sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0) ){
                sqlite3_bind_pointer(pStmt, 1,(void*)&pRet, "fts5_api_ptr", NULL);
                sqlite3_step(pStmt);
            }
            sqlite3_finalize(pStmt);
            return pRet;
        }

    /* Creates a SQL extension function. Tells sqlite which function to load as extension*/
    int sqlite3_extension_init(
        sqlite3 *db,
        char **pzErrMsg,
        const sqlite3_api_routines *pApi
    ){
        fts5_api *fpApi;
        fpApi = fts5_api_from_db(db);
        SQLITE_EXTENSION_INIT2(pApi);

        struct Builtin {
            const char *zFunc;                          /* Function name (nul-terminated) */
            void *pUserData;                            /* User-data pointer */
            fts5_extension_function xFunc;              /* Callback function */
            void (*xDestroy)(void*);                    /* Destructor function */
        } aBuiltin [] = {
                { "rankingMe", 0, rankprice, 0 },
        };
        int rc = SQLITE_OK;
        rc = fpApi->xCreateFunction(fpApi,
            aBuiltin[0].zFunc,
            aBuiltin[0].pUserData,
            aBuiltin[0].xFunc,
            aBuiltin[0].xDestroy
        );
        return rc;
    }

使用 gcc -shared -fPIC -g /var/www/rankprice.c -o /var/www/rankprice.so

确切的错误消息:

SQLite version 3.28.0 2019-04-16 19:49:53
Connected to a transient in-memory database.
sqlite> .load /var/www/rankprice.so
[2]    52632 segmentation fault (core dumped)  sqlite3

链接:
https://www.sqlite.org/fts5.html
https://github.com/sqlite/sqlite/blob/ff119f04b42a7ad3a16c306446af7e301d34026a/ext/fts5/fts5_aux.c

0 个答案:

没有答案