3

I'm trying to create a custom function for a SQLite database I'm using with Qt. I found information on how to create the function and it seems to work correctly on a x86 system.

Instead, it seems to be failing with a segfault on an ARM device. This is the code I wrote:

static bool createSQLiteFunctions(const QSqlDatabase& db)
{
// Get handle to the driver and check it is both valid and refers to SQLite3.
QVariant v = db.driver()->handle();
if (!v.isValid() || qstrcmp(v.typeName(), "sqlite3*") != 0) {
LOG_WARNING("Cannot get a sqlite3 handle to the driver.");
return false;
}

// Create a handler and attach functions.
sqlite3* handler = *static_cast<sqlite3**>(v.data());
if (!handler) {
LOG_WARNING("Cannot get a sqlite3 handler.");
return false;
}

// Check validity of the state.
if (!db.isValid()) {
LOG_ERROR("Cannot create SQLite custom functions: db object is not valid.");
return false;
}

if (!db.isOpen()) {
LOG_ERROR("Cannot create SQLite custom functions: db object is not open.");
return false;
}

if (sqlite3_create_function(handler, "_deleteFile", 1, SQLITE_ANY, 0, &_sqlite3DeleteFile, 0, 0))
LOG_ERROR("Cannot create SQLite functions: sqlite3_create_function failed.");

return true;
}

The db object is instantiated as a member of another object, which is calling this function in the constructor, where the connection to the db is established (multiple instances may be created concurrently, but sqlite3 is compiled with thread-safe option). It seems that no error log is printed and, but the sqlite3_create_function function gives a segfault. If I remove the call to createSQLiteFunctions everything works fine. Any idea why the result is a segfault? Thanks!

Luca Carlon
  • 9,546
  • 13
  • 59
  • 91

2 Answers2

1

QSql driver for sqlite3 can be linked to sqlite3 statically in the Qt library (using sqlite3 version of Qt repositories), or dynamically using the version of sqlite3 present on your system (i.e. in the sysroot when you're cross compiling for ARM).

The problem appears when the version of sqlite3 your application is linked against is different from the version linked in Qt, because this causes problems for instance with static variables which are initialized differently in the two version.

This problem is only visible when calling native sqlite3 functions on the handle retrieved from Qt, everything works perfectly as long as only QSqlDatabase functions are called, because this only uses the sqlite3 version statically linked in Qt.

Check the Qt configure option "system-sqlite", also be aware that this option is broken in some versions of Qt (see commit ced4d167a25b in qtbase repository).

Étienne
  • 4,773
  • 2
  • 33
  • 58
1

If it's failing on ARM, it may have to do something with compilation (what sqlite3 are you using?) or with the callback function itself (_sqlite3DeleteFile). How is it defined, where is it located / linked. Depending on the ARM (what ARM are you using) the processor can be very picky with alignment. Check your map file, perhaps the MMU-configuration, ...?

BTW: I would probably prefer to leave out the const, as we are modifying the db.

static bool createSQLiteFunctions(/*const*/ QSqlDatabase& db)

Can you debug-step into the sqlite3_create_function code? Can you produce a trace?

Jens
  • 6,173
  • 2
  • 24
  • 43
  • I'm using SQLite 3.7.3 on the ARM system, 3.7.4 on the x86 system. It is compiled with the thread-safe option enabled. But I couldn't find any related bug solved from 3.7.3 to 3.7.4. I don't currently have precise information about the final ARM, may this be related to such hardware-specific details? I think I can debug-step, but unfortunately I only get question marks when trying to use gdb, so no backtrace. According to the logs anyway, I am sure that the crash is inside the sqlite3_create_function, and none of the other logs I placed are produced, so parameters seem valid. Thanks! – Luca Carlon Jun 09 '11 at 22:56
  • 1
    After long time I tried again this removing the workaround I made to overcome this issue. It seems the same exact code is now working on the same ARM platform. I'm not sure what has changed, but I remember vaguely I fixed something in my toolchain. I suppose my sqlite header may have mismatched the related sqlite library. I'm not sure, but this may help somebody with the same issue in the future. You're first guess may thus be correct. – Luca Carlon Oct 11 '11 at 22:37