When running this program with Apple's Instruments memory profiler leaks are reported when the tree is balanced, stack crawls are related to the page cache.
1 sqlite3memtest sqlite3MemMalloc /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:21312 2 sqlite3memtest mallocWithAlarm /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:24996 3 sqlite3memtest sqlite3Malloc /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:25026 4 sqlite3memtest pcache1Alloc /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:45870 5 sqlite3memtest pcache1AllocPage /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:45966 6 sqlite3memtest pcache1FetchStage2 /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:46436 7 sqlite3memtest pcache1FetchNoMutex /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:46540 8 sqlite3memtest pcache1Fetch /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:46582 9 sqlite3memtest sqlite3PcacheFetch /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:45045 10 sqlite3memtest getPageNormal /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:52859 11 sqlite3memtest sqlite3PagerGet /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:53043 12 sqlite3memtest btreeGetPage /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:61558 13 sqlite3memtest btreeGetUnusedPage /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:61687 14 sqlite3memtest allocateBtreePage /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:65510 15 sqlite3memtest balance_quick /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:66464 16 sqlite3memtest balance /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:67554 17 sqlite3memtest sqlite3BtreeInsert /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:67811 18 sqlite3memtest sqlite3VdbeExec /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:83397 19 sqlite3memtest sqlite3Step /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:77352 20 sqlite3memtest sqlite3_step /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:77416 21 sqlite3memtest sqlite3_exec /KentDev/sqlite3memtest/sqlite3memtest/sqlite3.c:111930 22 sqlite3memtest main /KentDev/sqlite3memtest/sqlite3memtest/main.c:99 If I change the page_size pragma to 4096 (or leave it at the default) no leaks are reported by Instruments. A page_size of 16384 will also report leaks. I tried running valgrind on the app and but it doesn't report leaks. I think I see a similar leak if I interrupt the program. (valgrind reports them as a possible leak in this case) This is starting to make me think it may be a false positive but just thought I would check to make sure it isn't a leak. I've included the project which has the 3.20.1 amalgamation included within it. Thanks, Kent Carlson
#include <stdio.h> #include <string.h> #include <unistd.h> #include "sqlite3.h" static int showResults(void *notUsed, int argc, char **argv, char **colv){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", colv[i], argv[i] ? argv[i] : "NULL"); } return 0; } static void checkForError( char** errorMessage ) { if( *errorMessage ) { fprintf(stderr, "ERROR: %s\n", *errorMessage); sqlite3_free(*errorMessage); *errorMessage = 0; } } #define MAX_BLOB_SIZE 20000 int main(int argc, char **argv){ for( int times=0; times < 200; times++) { sqlite3 *db; unlink("memtest.db"); int resultCode = sqlite3_open("memtest.db", &db); if( resultCode != SQLITE_OK ){ fprintf(stderr, "cannot open 'memtest.db'\n"); return 1; } char *errorMessage = 0; sqlite3_exec(db, "PRAGMA page_size = 8192;", showResults, 0, &errorMessage ); checkForError( &errorMessage ); sqlite3_exec(db, "PRAGMA journal_mode = WAL;", showResults, 0, &errorMessage ); checkForError( &errorMessage ); sqlite3_exec(db, "PRAGMA synchronous = 1;", showResults, 0, &errorMessage ); checkForError( &errorMessage ); sqlite3_exec(db, "PRAGMA foreign_keys = true;", showResults, 0, &errorMessage ); checkForError( &errorMessage ); sqlite3_exec(db, "CREATE TABLE docs( localDocId INTEGER PRIMARY KEY," " fullDocId TEXT UNIQUE NOT NULL," " winningRevSequence INTEGER REFERENCES revs( sequence ) ON DELETE SET NULL," " mostRecentRevSequence INTEGER REFERENCES revs( sequence ) ON DELETE SET NULL," " deleted BOOLEAN DEFAULT 0," " hasConflicts BOOLEAN DEFAULT 0," " annotation BLOB );", showResults, 0, &errorMessage ); checkForError( &errorMessage ); sqlite3_exec(db, "CREATE TABLE revs( sequence INTEGER PRIMARY KEY AUTOINCREMENT," " localDocId INTEGER NOT NULL REFERENCES docs( localDocId ) ON DELETE CASCADE," " revId TEXT NOT NULL COLLATE BINARY," " parentRevSequence INTEGER REFERENCES revs( sequence ) ON DELETE SET NULL," " current BOOLEAN," " deleted BOOLEAN DEFAULT 0," " content BLOB );", showResults, 0, &errorMessage ); checkForError( &errorMessage ); char blob[MAX_BLOB_SIZE]; memset( blob, 'a', MAX_BLOB_SIZE ); blob[8000] = 0; int revLocalDocId = 1; for( int localId = 1; localId < 200; localId++ ) { char fullDocId[33]; char revId[33]; sprintf( fullDocId, "%032d", localId ); sprintf( revId, "%032d", revLocalDocId ); revLocalDocId = revLocalDocId + 1; char insertStatement[1024+MAX_BLOB_SIZE]; sprintf( insertStatement, "INSERT INTO docs( fullDocId ) VALUES( '%s' )", fullDocId ); sqlite3_exec(db, insertStatement, showResults, 0, &errorMessage); checkForError( &errorMessage ); sprintf( insertStatement, "INSERT INTO revs( localDocId, revId, parentRevSequence, current, deleted, content ) VALUES( %d, '%s', NULL, 1,0, '%s');", localId, revId, blob ); sqlite3_exec(db, insertStatement, showResults, 0, &errorMessage); checkForError( &errorMessage ); } sqlite3_close(db); } return 0; }
_______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users