/ Check-in [dce4cb84]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a large memory leak in the btree layer that occurs following an I/O error when in shared cache mode. (CVS 3776)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:dce4cb84930116db99275f77141fd933bc84288e
User & Date: drh 2007-03-31 02:36:44
Context
2007-03-31
03:59
Fix a long-standing memory leak in the hash table. The leak only appears following a malloc failure of a hash that copies its keys, which rarely happens and so we have not previously noticed it. (CVS 3777) check-in: 2aae1964 user: drh tags: trunk
02:36
Fix a large memory leak in the btree layer that occurs following an I/O error when in shared cache mode. (CVS 3776) check-in: dce4cb84 user: drh tags: trunk
01:34
Fix memory leaks in WHERE clause processing and in TRIGGER parsing. (CVS 3775) check-in: 6736f454 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.348 2007/03/30 20:43:41 drh Exp $
           12  +** $Id: btree.c,v 1.349 2007/03/31 02:36:44 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
   707    707         if( SQLITE_OK!=rc ){
   708    708           return rc;
   709    709         }
   710    710       }
   711    711     }
   712    712     return SQLITE_OK;
   713    713   }
          714  +
          715  +/*
          716  +** Clear the current cursor position.
          717  +*/
          718  +static void clearCursorPosition(BtCursor *pCur){
          719  +  sqliteFree(pCur->pKey);
          720  +  pCur->pKey = 0;
          721  +  pCur->eState = CURSOR_INVALID;
          722  +}
   714    723   
   715    724   /*
   716    725   ** Restore the cursor to the position it was in (or as close to as possible)
   717    726   ** when saveCursorPosition() was called. Note that this call deletes the 
   718    727   ** saved position info stored by saveCursorPosition(), so there can be
   719    728   ** at most one effective restoreOrClearCursorPosition() call after each 
   720    729   ** saveCursorPosition().
   721    730   **
   722    731   ** If the second argument argument - doSeek - is false, then instead of 
   723    732   ** returning the cursor to it's saved position, any saved position is deleted
   724    733   ** and the cursor state set to CURSOR_INVALID.
   725    734   */
   726         -static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
   727         -  int rc = SQLITE_OK;
          735  +static int restoreOrClearCursorPositionX(BtCursor *pCur){
          736  +  int rc;
   728    737     assert( pCur->eState==CURSOR_REQUIRESEEK );
   729    738     pCur->eState = CURSOR_INVALID;
   730         -  if( doSeek ){
   731         -    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
   732         -  }
          739  +  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
   733    740     if( rc==SQLITE_OK ){
   734    741       sqliteFree(pCur->pKey);
   735    742       pCur->pKey = 0;
   736         -    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
          743  +    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
   737    744     }
   738    745     return rc;
   739    746   }
   740    747   
   741         -#define restoreOrClearCursorPosition(p,x) \
   742         -  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
          748  +#define restoreOrClearCursorPosition(p) \
          749  +  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p):SQLITE_OK)
   743    750   
   744    751   #ifndef SQLITE_OMIT_AUTOVACUUM
   745    752   /*
   746    753   ** These macros define the location of the pointer-map entry for a 
   747    754   ** database page. The first argument to each is the number of usable
   748    755   ** bytes on each page of the database (often 1024). The second is the
   749    756   ** page number to look up in the pointer map.
................................................................................
  2824   2831   
  2825   2832   /*
  2826   2833   ** Close a cursor.  The read lock on the database file is released
  2827   2834   ** when the last cursor is closed.
  2828   2835   */
  2829   2836   int sqlite3BtreeCloseCursor(BtCursor *pCur){
  2830   2837     BtShared *pBt = pCur->pBtree->pBt;
  2831         -  restoreOrClearCursorPosition(pCur, 0);
         2838  +  clearCursorPosition(pCur);
  2832   2839     if( pCur->pPrev ){
  2833   2840       pCur->pPrev->pNext = pCur->pNext;
  2834   2841     }else{
  2835   2842       pBt->pCursor = pCur->pNext;
  2836   2843     }
  2837   2844     if( pCur->pNext ){
  2838   2845       pCur->pNext->pPrev = pCur->pPrev;
................................................................................
  2891   2898   ** the key for the current entry.  If the cursor is not pointing
  2892   2899   ** to a valid entry, *pSize is set to 0. 
  2893   2900   **
  2894   2901   ** For a table with the INTKEY flag set, this routine returns the key
  2895   2902   ** itself, not the number of bytes in the key.
  2896   2903   */
  2897   2904   int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  2898         -  int rc = restoreOrClearCursorPosition(pCur, 1);
         2905  +  int rc = restoreOrClearCursorPosition(pCur);
  2899   2906     if( rc==SQLITE_OK ){
  2900   2907       assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
  2901   2908       if( pCur->eState==CURSOR_INVALID ){
  2902   2909         *pSize = 0;
  2903   2910       }else{
  2904   2911         getCellInfo(pCur);
  2905   2912         *pSize = pCur->info.nKey;
................................................................................
  2912   2919   ** Set *pSize to the number of bytes of data in the entry the
  2913   2920   ** cursor currently points to.  Always return SQLITE_OK.
  2914   2921   ** Failure is not possible.  If the cursor is not currently
  2915   2922   ** pointing to an entry (which can happen, for example, if
  2916   2923   ** the database is empty) then *pSize is set to 0.
  2917   2924   */
  2918   2925   int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  2919         -  int rc = restoreOrClearCursorPosition(pCur, 1);
         2926  +  int rc = restoreOrClearCursorPosition(pCur);
  2920   2927     if( rc==SQLITE_OK ){
  2921   2928       assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
  2922   2929       if( pCur->eState==CURSOR_INVALID ){
  2923   2930         /* Not pointing at a valid entry - set *pSize to 0. */
  2924   2931         *pSize = 0;
  2925   2932       }else{
  2926   2933         getCellInfo(pCur);
................................................................................
  3027   3034   ** begins at "offset".
  3028   3035   **
  3029   3036   ** Return SQLITE_OK on success or an error code if anything goes
  3030   3037   ** wrong.  An error is returned if "offset+amt" is larger than
  3031   3038   ** the available payload.
  3032   3039   */
  3033   3040   int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  3034         -  int rc = restoreOrClearCursorPosition(pCur, 1);
         3041  +  int rc = restoreOrClearCursorPosition(pCur);
  3035   3042     if( rc==SQLITE_OK ){
  3036   3043       assert( pCur->eState==CURSOR_VALID );
  3037   3044       assert( pCur->pPage!=0 );
  3038   3045       if( pCur->pPage->intKey ){
  3039   3046         return SQLITE_CORRUPT_BKPT;
  3040   3047       }
  3041   3048       assert( pCur->pPage->intKey==0 );
................................................................................
  3051   3058   ** begins at "offset".
  3052   3059   **
  3053   3060   ** Return SQLITE_OK on success or an error code if anything goes
  3054   3061   ** wrong.  An error is returned if "offset+amt" is larger than
  3055   3062   ** the available payload.
  3056   3063   */
  3057   3064   int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  3058         -  int rc = restoreOrClearCursorPosition(pCur, 1);
         3065  +  int rc = restoreOrClearCursorPosition(pCur);
  3059   3066     if( rc==SQLITE_OK ){
  3060   3067       assert( pCur->eState==CURSOR_VALID );
  3061   3068       assert( pCur->pPage!=0 );
  3062   3069       assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  3063   3070       rc = getPayload(pCur, offset, amt, pBuf, 1);
  3064   3071     }
  3065   3072     return rc;
................................................................................
  3220   3227   ** Move the cursor to the root page
  3221   3228   */
  3222   3229   static int moveToRoot(BtCursor *pCur){
  3223   3230     MemPage *pRoot;
  3224   3231     int rc = SQLITE_OK;
  3225   3232     BtShared *pBt = pCur->pBtree->pBt;
  3226   3233   
  3227         -  restoreOrClearCursorPosition(pCur, 0);
         3234  +  if( pCur->eState==CURSOR_REQUIRESEEK ){
         3235  +    clearCursorPosition(pCur);
         3236  +  }
  3228   3237     pRoot = pCur->pPage;
  3229   3238     if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
  3230   3239       assert( pRoot->isInit );
  3231   3240     }else{
  3232   3241       if( 
  3233   3242         SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
  3234   3243       ){
................................................................................
  3498   3507   ** this routine was called, then set *pRes=1.
  3499   3508   */
  3500   3509   int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  3501   3510     int rc;
  3502   3511     MemPage *pPage;
  3503   3512   
  3504   3513   #ifndef SQLITE_OMIT_SHARED_CACHE
  3505         -  rc = restoreOrClearCursorPosition(pCur, 1);
         3514  +  rc = restoreOrClearCursorPosition(pCur);
  3506   3515     if( rc!=SQLITE_OK ){
  3507   3516       return rc;
  3508   3517     }
  3509   3518     if( pCur->skip>0 ){
  3510   3519       pCur->skip = 0;
  3511   3520       *pRes = 0;
  3512   3521       return SQLITE_OK;
................................................................................
  3566   3575   */
  3567   3576   int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  3568   3577     int rc;
  3569   3578     Pgno pgno;
  3570   3579     MemPage *pPage;
  3571   3580   
  3572   3581   #ifndef SQLITE_OMIT_SHARED_CACHE
  3573         -  rc = restoreOrClearCursorPosition(pCur, 1);
         3582  +  rc = restoreOrClearCursorPosition(pCur);
  3574   3583     if( rc!=SQLITE_OK ){
  3575   3584       return rc;
  3576   3585     }
  3577   3586     if( pCur->skip<0 ){
  3578   3587       pCur->skip = 0;
  3579   3588       *pRes = 0;
  3580   3589       return SQLITE_OK;
................................................................................
  5275   5284       return SQLITE_PERM;   /* Cursor not open for writing */
  5276   5285     }
  5277   5286     if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
  5278   5287       return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  5279   5288     }
  5280   5289   
  5281   5290     /* Save the positions of any other cursors open on this table */
  5282         -  restoreOrClearCursorPosition(pCur, 0);
         5291  +  clearCursorPosition(pCur);
  5283   5292     if( 
  5284   5293       SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
  5285   5294       SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
  5286   5295     ){
  5287   5296       return rc;
  5288   5297     }
  5289   5298   
................................................................................
  5362   5371   
  5363   5372     /* Restore the current cursor position (a no-op if the cursor is not in 
  5364   5373     ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors 
  5365   5374     ** open on the same table. Then call sqlite3PagerWrite() on the page
  5366   5375     ** that the entry will be deleted from.
  5367   5376     */
  5368   5377     if( 
  5369         -    (rc = restoreOrClearCursorPosition(pCur, 1))!=0 ||
         5378  +    (rc = restoreOrClearCursorPosition(pCur))!=0 ||
  5370   5379       (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
  5371   5380       (rc = sqlite3PagerWrite(pPage->pDbPage))!=0
  5372   5381     ){
  5373   5382       return rc;
  5374   5383     }
  5375   5384   
  5376   5385     /* Locate the cell within it's page and leave pCell pointing to the
................................................................................
  5979   5988   ** This routine is used for testing and debugging only.
  5980   5989   */
  5981   5990   int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
  5982   5991     int cnt, idx;
  5983   5992     MemPage *pPage = pCur->pPage;
  5984   5993     BtCursor tmpCur;
  5985   5994   
  5986         -  int rc = restoreOrClearCursorPosition(pCur, 1);
         5995  +  int rc = restoreOrClearCursorPosition(pCur);
  5987   5996     if( rc!=SQLITE_OK ){
  5988   5997       return rc;
  5989   5998     }
  5990   5999   
  5991   6000     assert( pPage->isInit );
  5992   6001     getTempCursor(pCur, &tmpCur);
  5993   6002     while( upCnt-- ){