SQLite是否使用SQLCipher扩展泄漏内存

Does SQLite leak memory with the SQLCipher extension?

本文关键字:扩展 泄漏 内存 SQLCipher 是否 SQLite      更新时间:2023-10-16

我正在使用SQLCipher来存储加密的SQLite数据库。然而,当我使用sqlite3_key加密数据库时,我开始出现内存泄漏。观察以下样品:

#include <sqlite3.h>    
int main()
{
    sqlite3 * connection;
    sqlite3_open_v2(":memory:", &connection, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
    sqlite3_key(connection, "passphrase", 10);
    sqlite3_close(connection);
}

此示例会导致内存泄漏。如果我删除对sqlite3_key的调用,内存泄漏就会消失。

我已经缩小了一些可能的罪魁祸首:

  • 尽管示例使用内存中数据库(因此":memory:"),但在使用基于文件的数据库时,我看到了相同的结果
  • 来自sqlite3_*调用的所有返回代码都是SQLITE_OK,这意味着没有任何错误
  • "passphrase"10的缓冲区长度不是问题

然而,无论我创建了多少连接或使用了多少不同的加密密钥,内存泄漏总是大约8千字节。这让我怀疑这实际上不是内存泄漏,而是SQLite/SQLCipher中的一些恒定全局内存,不会手动释放。

以前有人经历过这种情况吗?有没有办法消除泄漏?即使这不是官方的内存泄漏,也很难检测到真正的内存泄漏。

我使用的是适用于Windows的SQLCipher库。

我对此进行了进一步的研究,这些报告的泄漏是OpenSSL分配内存的结果。由于SQLCipher不知道应用程序何时严格使用它,因此不会调用EVP_cleanup(),并且valgrind将内存报告为泄漏。我们正在进行一个简单的修复,该修复将尝试通过一些简单的引用计数来识别SQLCipher何时不再使用OpenSSL结构,从而可以自动调用EVP_cleanup()

在下次发布SQLCipher之前,作为一个快速解决方法,您可以在退出之前在程序中手动调用EVP_cleanup()