]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a large memory leak in the btree layer
authordrh <drh@noemail.net>
Sat, 31 Mar 2007 02:36:44 +0000 (02:36 +0000)
committerdrh <drh@noemail.net>
Sat, 31 Mar 2007 02:36:44 +0000 (02:36 +0000)
that occurs following an I/O error when in shared cache mode. (CVS 3776)

FossilOrigin-Name: dce4cb84930116db99275f77141fd933bc84288e

manifest
manifest.uuid
src/btree.c

index a4746fb972e9af81901d8f0376ec56cff22688ef..133b0c6626cec1a6a5b9916312c4e0b9485ec8e8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\smemory\sleaks\sin\sWHERE\sclause\sprocessing\sand\sin\sTRIGGER\sparsing.\s(CVS\s3775)
-D 2007-03-31T01:34:45
+C Fix\sa\slarge\smemory\sleak\sin\sthe\sbtree\slayer\nthat\soccurs\sfollowing\san\sI/O\serror\swhen\sin\sshared\scache\smode.\s(CVS\s3776)
+D 2007-03-31T02:36:44
 F Makefile.in 2f2c3bf69faf0ae7b8e8af4f94f1986849034530
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -58,7 +58,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
 F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
 F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
 F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
-F src/btree.c ef4a874b7b45dbfd26753088084594c39f3a1703
+F src/btree.c 052d0306d66768ad4d5a54609d4464bdc2a17839
 F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
 F src/build.c ad3374b5409554e504300f77e1fbc6b4c106a57f
 F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
@@ -447,7 +447,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P e5e8d56397acf041aeaf5361381eb22eb1554759
-R b77a60cf177b17327f9b7e624826632c
+P 6736f4547c0cc2123d1a19ed2d6915712718d22e
+R 488be4ffadef0d522e3de226e0170295
 U drh
-Z bf47571d4a3cac7d92437a7c798ec8c5
+Z 940217d7b5c1abc16778694d39dfaa5f
index 5bd5f73039886695c3d09cd6611940db3013590a..ff57b4bbad277b011be44b43f767a887c1a3c29c 100644 (file)
@@ -1 +1 @@
-6736f4547c0cc2123d1a19ed2d6915712718d22e
\ No newline at end of file
+dce4cb84930116db99275f77141fd933bc84288e
\ No newline at end of file
index f6d2efc7c37e0ed1e8cd604d3cc442a807e6a91a..a85d14ba58dd652ab3c9c53ddf51a8c9b5971ca8 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.348 2007/03/30 20:43:41 drh Exp $
+** $Id: btree.c,v 1.349 2007/03/31 02:36:44 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -712,6 +712,15 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
   return SQLITE_OK;
 }
 
+/*
+** Clear the current cursor position.
+*/
+static void clearCursorPosition(BtCursor *pCur){
+  sqliteFree(pCur->pKey);
+  pCur->pKey = 0;
+  pCur->eState = CURSOR_INVALID;
+}
+
 /*
 ** Restore the cursor to the position it was in (or as close to as possible)
 ** when saveCursorPosition() was called. Note that this call deletes the 
@@ -723,23 +732,21 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
 ** returning the cursor to it's saved position, any saved position is deleted
 ** and the cursor state set to CURSOR_INVALID.
 */
-static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
-  int rc = SQLITE_OK;
+static int restoreOrClearCursorPositionX(BtCursor *pCur){
+  int rc;
   assert( pCur->eState==CURSOR_REQUIRESEEK );
   pCur->eState = CURSOR_INVALID;
-  if( doSeek ){
-    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
-  }
+  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
   if( rc==SQLITE_OK ){
     sqliteFree(pCur->pKey);
     pCur->pKey = 0;
-    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
+    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
   }
   return rc;
 }
 
-#define restoreOrClearCursorPosition(p,x) \
-  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
+#define restoreOrClearCursorPosition(p) \
+  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p):SQLITE_OK)
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
@@ -2828,7 +2835,7 @@ void sqlite3BtreeSetCompare(
 */
 int sqlite3BtreeCloseCursor(BtCursor *pCur){
   BtShared *pBt = pCur->pBtree->pBt;
-  restoreOrClearCursorPosition(pCur, 0);
+  clearCursorPosition(pCur);
   if( pCur->pPrev ){
     pCur->pPrev->pNext = pCur->pNext;
   }else{
@@ -2895,7 +2902,7 @@ static void getCellInfo(BtCursor *pCur){
 ** itself, not the number of bytes in the key.
 */
 int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
     if( pCur->eState==CURSOR_INVALID ){
@@ -2916,7 +2923,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
 ** the database is empty) then *pSize is set to 0.
 */
 int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
     if( pCur->eState==CURSOR_INVALID ){
@@ -3031,7 +3038,7 @@ static int getPayload(
 ** the available payload.
 */
 int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
@@ -3055,7 +3062,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
 ** the available payload.
 */
 int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
@@ -3224,7 +3231,9 @@ static int moveToRoot(BtCursor *pCur){
   int rc = SQLITE_OK;
   BtShared *pBt = pCur->pBtree->pBt;
 
-  restoreOrClearCursorPosition(pCur, 0);
+  if( pCur->eState==CURSOR_REQUIRESEEK ){
+    clearCursorPosition(pCur);
+  }
   pRoot = pCur->pPage;
   if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
     assert( pRoot->isInit );
@@ -3502,7 +3511,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   MemPage *pPage;
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
-  rc = restoreOrClearCursorPosition(pCur, 1);
+  rc = restoreOrClearCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -3570,7 +3579,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
   MemPage *pPage;
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
-  rc = restoreOrClearCursorPosition(pCur, 1);
+  rc = restoreOrClearCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -5279,7 +5288,7 @@ int sqlite3BtreeInsert(
   }
 
   /* Save the positions of any other cursors open on this table */
-  restoreOrClearCursorPosition(pCur, 0);
+  clearCursorPosition(pCur);
   if( 
     SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
     SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
@@ -5366,7 +5375,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
   ** that the entry will be deleted from.
   */
   if( 
-    (rc = restoreOrClearCursorPosition(pCur, 1))!=0 ||
+    (rc = restoreOrClearCursorPosition(pCur))!=0 ||
     (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
     (rc = sqlite3PagerWrite(pPage->pDbPage))!=0
   ){
@@ -5983,7 +5992,7 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
   MemPage *pPage = pCur->pPage;
   BtCursor tmpCur;
 
-  int rc = restoreOrClearCursorPosition(pCur, 1);
+  int rc = restoreOrClearCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }