]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix memory leaks on this branch.
authordan <dan@noemail.net>
Tue, 5 Feb 2019 19:15:36 +0000 (19:15 +0000)
committerdan <dan@noemail.net>
Tue, 5 Feb 2019 19:15:36 +0000 (19:15 +0000)
FossilOrigin-Name: e9c5e1891ff4f7e57131031f068efea87027ddab0cd7846e0514a105853be47d

manifest
manifest.uuid
src/callback.c
src/main.c
src/prepare.c
src/sqliteInt.h
test/reuse1.test
test/tester.tcl

index 3c9508c1609432962ff425115f0769b508eedc15..340dcf0c5bf66d75042756a05ba81c4e0e7aadbf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\swith\sreloading\sthe\sschema\son\sthis\sbranch.
-D 2019-02-04T21:02:00.454
+C Fix\smemory\sleaks\son\sthis\sbranch.
+D 2019-02-05T19:15:36.531
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in edbb6e20bb1decf65f6c64c9e61004a69bdf8afb39cdce5337c916b03dfcd1e3
@@ -449,7 +449,7 @@ F src/btree.c 3ef104ecae8b1b5f0458be1f5fa7c1ecf25fdc322a9d63bb8151f89eb32d381e
 F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
 F src/build.c 6466a704dbf63090db20434e0cecbc04b005b2fbbaff505282fbc149a0e0537c
-F src/callback.c 382a6e9073bc46aa68b9062843577f9ba21c7e0ae542517ec0526cedf65b7556
+F src/callback.c 7e4f5445db375d4620af892077215dcced0177970137de6331c8735022342b86
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
 F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
@@ -468,7 +468,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c 6b81aae27b196925d8ff78824f4bbd435d6a40cd38dc324685e21735bb402109
 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
 F src/loadext.c 448eab53ecdb566a1259ee2d45ebff9c0bc4a2cf393774488775c33e4fbe89bf
-F src/main.c 75e429a1130d7c32e31bb43a86240e5e50e0414d7330367c2bacd92842651dcb
+F src/main.c 23f7d6395e30d9fbd2abfe4e5bae6c9bf8ce5e854d15e934ca9571c22eb3eef5
 F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -499,7 +499,7 @@ F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
 F src/pragma.c 0bb05b1788d7af5fdc7f40f5655a79a140dece8fd2523402eb2103925e4739c2
 F src/pragma.h fdd03d78a7497f74a3f652909f945328480089189526841ae829ce7313d98d13
-F src/prepare.c a1f7b15ec6e91602ca8193cf322cee443417995577d8543cfc07b71258d7b745
+F src/prepare.c 24812a79d17c4271b3989d7f2891bc16bb0c87e43806ede192fe0c4e2b283ed4
 F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c bc8c79e56439b111e7d9415e44940951f7087e9466c3a9d664558ef0faf31073
@@ -509,7 +509,7 @@ F src/shell.c.in 9f517c22e3c9a08ab634330789f74454ec9a7e0596c8faed221c6b43ee980b9
 F src/sqlite.h.in 29a3b2eab328c5a345ef6be09ff77dc6dabbfe1a36e05c19204591d084a73d80
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
-F src/sqliteInt.h 8058f6127b3721c8f64899662c795776ddc1d2c6269cef72f7deecc9e2070813
+F src/sqliteInt.h 3fa010615553494385ca7ac03d6815393171f52aa7d1858cda8506c6d89e9d2c
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 41d9cc5d5f9d2a470dcf0a28432c66e25c15b86e51535283e9aef632adf02ac8
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1205,7 +1205,7 @@ F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
 F test/releasetest.tcl c5b474f9880073fc3b69729ee05d5284653a9ee101af572204917d9dcb1d9015 x
 F test/resetdb.test 684a6ffde5a5141bba79f3101981cc38dcfc3403f61e643b7b3aa68bef0b8408
 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
-F test/reuse1.test 04ae701b4000113fedc472719e4cf4bb1d34d22dcaf8d3e643d41d1256a9590d
+F test/reuse1.test b020ae24435771c741f322f3e97c2b1777ab33d0e149cb15f86b1e19ed98b3cb
 F test/reuse2.test 39f4a78ddf2d9b1fe3e4131c70497db628cd3a313a4520860b98af2e024bf98d
 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
 F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6
@@ -1354,7 +1354,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
-F test/tester.tcl fa5656391e3b477508abe12b3b81f019b2e71397399ab38a2f32d8d7f3bf8e56
+F test/tester.tcl f30331b201b960eba5bae41cce1b7b8e32c24defe81454855538a5d948d33633
 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1778,7 +1778,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9e8e5f52cf90579c3071f04a3c6857bb76b4ca1b1900a7f865de789ed0bb8678
-R e01fb302d94f7539dc0f104a82b482ef
+P 5dfbef8349e47f9d9fcdbb648ecd18b5bc7eebdb1a3ddaf91789d036b7de8a90
+R afc552fccf62fcbff9210a438b2241ca
 U dan
-Z 91d18e9112ddb36206700fa8a4c225cf
+Z 9f5446cffa6464b6e56079738d9c74c0
index f4f7357b8b31190748300ec72637534cdb543eda..ed771f57bd78af172d5480550923fa1d0448d27f 100644 (file)
@@ -1 +1 @@
-5dfbef8349e47f9d9fcdbb648ecd18b5bc7eebdb1a3ddaf91789d036b7de8a90
\ No newline at end of file
+e9c5e1891ff4f7e57131031f068efea87027ddab0cd7846e0514a105853be47d
\ No newline at end of file
index 2438045e42198865b072c0deef4265c7df0dc002..eb1c2278259c97acb6b2899088dc6ca3a1ada0c2 100644 (file)
 
 #include "sqliteInt.h"
 
+/*
+** Connections opened with the SQLITE_OPEN_REUSE_SCHEMA flag specified
+** may use SchemaPool objects for any database that is not the temp db
+** (iDb==1). For such databases (type "struct Db") there are three states
+** the Schema/SchemaPool object may be in.
+**
+**   1) pSPool==0, pSchema points to an empty object allocated by
+**      sqlite3_malloc(). DB_SchemaLoaded flag is clear.
+**
+**   2) pSPool!=0, pSchema points to a populated object owned by the
+**      SchemaPool. DB_SchemaLoaded flag is set.
+**
+**   3) pSPool!=0, pSchema points to the SchemaPool's static object
+**      (SchemaPool.sSchema).
+*/
 struct SchemaPool {
   int nRef;                       /* Number of pointers to this object */
   u64 cksum;                      /* Checksum for this Schema contents */
@@ -24,6 +39,36 @@ struct SchemaPool {
   SchemaPool *pNext;              /* Next element in schemaPoolList */
 };
 
+#ifdef SQLITE_DEBUG
+static void assert_schema_state_ok(sqlite3 *db){
+  if( IsReuseSchema(db) ){
+    int i;
+    for(i=0; i<db->nDb; i++){
+      if( i!=1 ){
+        Db *pDb = &db->aDb[i];
+        Btree *pBt = pDb->pBt;
+        if( pDb->pSPool ){
+          if( DbHasProperty(db, i, DB_SchemaLoaded)==0 ){
+            assert( pDb->pSchema->tblHash.count==0 );
+            assert( pDb->pSchema==&pDb->pSPool->sSchema );
+          }else{
+            assert( pBt==0 || pDb->pSchema!=sqlite3BtreeSchema(pBt, 0, 0) );
+            assert( pDb->pSchema!=&pDb->pSPool->sSchema );
+          }
+        }else{
+          assert( DbHasProperty(db, i, DB_SchemaLoaded)==0 );
+          assert( pDb->pSchema->tblHash.count==0 );
+          assert( pBt==0 || pDb->pSchema!=sqlite3BtreeSchema(pBt, 0, 0) );
+          assert( pDb->pSchema!=&pDb->pSPool->sSchema );
+        }
+      }
+    }
+  }
+}
+#else
+# define assert_schema_state_ok(x)
+#endif
+
 /*
 ** Invoke the 'collation needed' callback to request a collation sequence
 ** in the encoding enc of name zName, length nName.
@@ -493,7 +538,7 @@ void sqlite3SchemaZero(sqlite3 *db, int iDb){
     if( pDb->pSPool ){
       Schema *pNew = sqlite3SchemaGet(db, 0);
       if( pNew ){
-        sqlite3SchemaDisconnect(db, iDb);
+        sqlite3SchemaDisconnect(db, iDb, 0);
         pDb->pSchema = pNew;
       }
       return;
@@ -527,6 +572,18 @@ static void schemaDelete(Schema *pSchema){
   sqlite3_free(pSchema);
 }
 
+static void schemaRelease(Db *pDb){
+  assert( pDb->pSPool && pDb->pSchema );
+  assert( pDb->pSchema->schemaFlags & DB_SchemaLoaded );
+  assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
+
+  pDb->pSchema->pNext = pDb->pSPool->pSchema;
+  pDb->pSPool->pSchema = pDb->pSchema;
+  pDb->pSchema = &pDb->pSPool->sSchema;
+
+  assert( (pDb->pSchema->schemaFlags & DB_SchemaLoaded)==0 );
+}
+
 /*
 ** The schema for database iDb of database handle db, which was opened
 ** with SQLITE_OPEN_REUSE_SCHEMA, has just been parsed. This function either
@@ -580,30 +637,53 @@ int sqlite3SchemaConnect(sqlite3 *db, int iDb, u64 cksum){
   return (p ? SQLITE_OK : SQLITE_NOMEM);
 }
 
-void sqlite3SchemaDisconnect(sqlite3 *db, int iDb){
-  Db *pDb = &db->aDb[iDb];
-  if( pDb->pSPool ){
+int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){
+  int rc = SQLITE_OK;
+  if( IsReuseSchema(db) && iDb!=1 ){
+    Db *pDb = &db->aDb[iDb];
     SchemaPool *pSPool = pDb->pSPool;
-    pDb->pSPool = 0;
-    assert( iDb!=1 );
+    assert_schema_state_ok(db);
+    assert( pDb->pSchema );
 
-    sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
-    assert( pSPool->nRef>=1 );
-    pSPool->nRef--;
-    if( pSPool->nRef<=0 ){
-      Schema *pNext;
-      SchemaPool **pp;
-      while( pSPool->pSchema ){
-        Schema *pNext = pSPool->pSchema->pNext;
-        schemaDelete(pSPool->pSchema);
-        pSPool->pSchema = pNext;
+    if( pSPool==0 ){
+      if( bNew==0 ){
+        schemaDelete(pDb->pSchema);
+        pDb->pSchema = 0;
+      }
+    }else{
+      sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
+      if( DbHasProperty(db, iDb, DB_SchemaLoaded) ){
+        schemaRelease(pDb);
+      }
+      if( bNew ){
+        Schema *pNew = sqlite3SchemaGet(db, 0);
+        if( pNew==0 ){
+          rc = SQLITE_NOMEM;
+        }else{
+          pDb->pSchema = pNew;
+        }
+      }
+      if( rc==SQLITE_OK ){
+        assert( pSPool->nRef>=1 );
+        pDb->pSPool = 0;
+        pSPool->nRef--;
+        if( pSPool->nRef<=0 ){
+          Schema *pNext;
+          SchemaPool **pp;
+          while( pSPool->pSchema ){
+            Schema *pNext = pSPool->pSchema->pNext;
+            schemaDelete(pSPool->pSchema);
+            pSPool->pSchema = pNext;
+          }
+          for(pp=&schemaPoolList; (*pp)!=pSPool; pp=&((*pp)->pNext));
+          *pp = pSPool->pNext;
+          sqlite3_free(pSPool);
+        }
       }
-      for(pp=&schemaPoolList; (*pp)!=pSPool; pp=&((*pp)->pNext));
-      *pp = pSPool->pNext;
-      sqlite3_free(pSPool);
+      sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
     }
-    sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
   }
+  return rc;
 }
 
 /*
@@ -627,19 +707,17 @@ Schema *sqlite3SchemaExtract(SchemaPool *pSPool){
 
 void sqlite3SchemaReleaseAll(sqlite3 *db){
   int i;
+  assert_schema_state_ok(db);
+  sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
   for(i=0; i<db->nDb; i++){
     if( i!=1 ){
       Db *pDb = &db->aDb[i];
       if( pDb->pSPool && pDb->pSchema && DbHasProperty(db,i,DB_SchemaLoaded) ){
-        sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
-        pDb->pSchema->pNext = pDb->pSPool->pSchema;
-        pDb->pSPool->pSchema = pDb->pSchema;
-        pDb->pSchema = &pDb->pSPool->sSchema;
-        assert( DbHasProperty(db, i, DB_SchemaLoaded)==0 );
-        sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
+        schemaRelease(pDb);
       }
     }
   }
+  sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
 }
 
 /*
index 25476ba88d6953e0f9679c068fe947caedee9b8d..c5e86ded245c405f5229c3f947882ab19e323cb1 100644 (file)
@@ -1185,7 +1185,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
       sqlite3BtreeClose(pDb->pBt);
       pDb->pBt = 0;
       if( j!=1 ){
-        sqlite3SchemaDisconnect(db, j);
+        sqlite3SchemaDisconnect(db, j, 0);
         pDb->pSchema = 0;
       }
     }
index 1e8095faba2ef6d11543b0c4593aced1662e780d..48a4bf55e6de6ce18db2cd9068bc2eb0a571856b 100644 (file)
@@ -192,13 +192,9 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
     if( (pDb->pSchema = sqlite3SchemaExtract(pDb->pSPool)) ){
       return SQLITE_OK;
     }
-    sqlite3SchemaDisconnect(db, iDb);
-    assert( pDb->pSchema==0 && pDb->pSPool==0 );
-    pDb->pSchema = sqlite3SchemaGet(db, 0);
-    if( pDb->pSchema==0 ){
-      rc = SQLITE_NOMEM_BKPT;
-      goto error_out;
-    }
+    rc = sqlite3SchemaDisconnect(db, iDb, 1);
+    if( rc!=SQLITE_OK ) goto error_out;
+    assert( pDb->pSchema && pDb->pSPool==0 );
   }
 
   db->init.busy = 1;
index 7518793caff2e3e59e291e5453d175009e5de550..12191d4052fc065766d96d66ed67c2ec36d0ab8d 100644 (file)
@@ -4294,7 +4294,7 @@ void sqlite3RegisterLikeFunctions(sqlite3*, int);
 int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
 void sqlite3SchemaClear(void *);
 int sqlite3SchemaConnect(sqlite3*, int, u64);
-void sqlite3SchemaDisconnect(sqlite3 *, int);
+int sqlite3SchemaDisconnect(sqlite3 *, int, int);
 void sqlite3SchemaZero(sqlite3*, int);
 Schema *sqlite3SchemaExtract(SchemaPool*);
 void sqlite3SchemaReleaseAll(sqlite3 *);
index b21779b9947cbb4d3a6232a564b6ddbea77ffa88..8c58c50aefcc46fe584b7de1ff19a893487e2a94 100644 (file)
@@ -36,7 +36,7 @@ do_test 1.2 {
   db close
   db2 close
   sqlite3 db2 test.db2 -reuse-schema 1
-  sqlite3 db  test.db -reuse-schema 1
+  sqlite3 db test.db -reuse-schema 1
 } {}
 
 do_execsql_test -db db2 1.3.1 {
index 14808d9cd912819afa6775539260508e5a4a2245..06bb06d0c0bf4883f19afb0c25512bcd5f7bbd89 100644 (file)
@@ -2048,9 +2048,11 @@ proc memdebug_log_sql {filename} {
   set tbl2 "CREATE TABLE ${database}.frame(frame INTEGER PRIMARY KEY, line);\n"
   set tbl3 "CREATE TABLE ${database}.file(name PRIMARY KEY, content);\n"
 
+  set pid [pid]
+
   foreach f [array names frames] {
     set addr [format %x $f]
-    set cmd "addr2line -e [info nameofexec] $addr"
+    set cmd "eu-addr2line --pid=$pid $addr"
     set line [eval exec $cmd]
     append sql "INSERT INTO ${database}.frame VALUES($f, '$line');\n"