5

暗号化されたSQLiteデータベースを格納するためにSQLCipherを使用しています。ただし、データベースの暗号化に使用すると、メモリ リークが発生し始めます。次のサンプルを確認してください。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エラーがないことを意味します。
  • 10forのバッファ長は"passphrase"問題ではありません。

ただし、作成する接続の数や使用する異なる暗号化キーの数に関係なく、メモリ リークは常に約 8 キロバイトです。これにより、これは実際にはメモリ リークではなく、手動で解放されない SQLite/SQLCipher の一定のグローバル メモリであると思われます。

誰もこれを経験したことがありますか?漏れをなくす方法はありますか?これが正式なメモリ リークではない場合でも、これを使用して実際のメモリ リークを検出することは困難です。

Windows 用の SQLCipher ライブラリを使用しています。

4

1 に答える 1

2

これについてもう少し詳しく調べましたが、これらの報告されたリークは、OpenSSLによって割り当てられたメモリの結果です。SQLCipherは、アプリがそれを使用して厳密に実行された時期を認識しないため、EVP_cleanup()呼び出されず、メモリはvalgrindによってリークとして報告されます。私たちは、OpenSSL構造がSQLCipherによって使用されなくなったときに、いくつかの単純な参照カウントを使用して識別しようとする単純な修正に取り組んでいるため、EVP_cleanup()自動的に呼び出すことができます。

SQLCipherの次のリリースの前にこれを回避するための簡単な回避策として、EVP_cleanup()終了する前にプログラムを手動で呼び出すことができます。

于 2012-10-02T15:58:36.010 に答える