From: drh Date: Sat, 31 Mar 2007 02:36:44 +0000 (+0000) Subject: Fix a large memory leak in the btree layer X-Git-Tag: version-3.6.10~2394 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bf700f3d3da076edcc58d683dece6189c7937daa;p=thirdparty%2Fsqlite.git Fix a large memory leak in the btree layer that occurs following an I/O error when in shared cache mode. (CVS 3776) FossilOrigin-Name: dce4cb84930116db99275f77141fd933bc84288e --- diff --git a/manifest b/manifest index a4746fb972..133b0c6626 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 5bd5f73039..ff57b4bbad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6736f4547c0cc2123d1a19ed2d6915712718d22e \ No newline at end of file +dce4cb84930116db99275f77141fd933bc84288e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index f6d2efc7c3..a85d14ba58 100644 --- a/src/btree.c +++ b/src/btree.c @@ -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; }