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

Reply via email to