SQLite

Check-in [b752906e70]
Login

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

Overview
Comment:Fix some minor problems with malloc failure and in-memory databases. (CVS 4527)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b752906e708e1c8c76084152f5829e16e8988ef2
User & Date: danielk1977 2007-11-05 15:30:13.000
Context
2007-11-05
17:01
Reset the writer-thread halt criteria after halting the thread. (CVS 4528) (check-in: ecbff972a1 user: danielk1977 tags: trunk)
15:30
Fix some minor problems with malloc failure and in-memory databases. (CVS 4527) (check-in: b752906e70 user: danielk1977 tags: trunk)
14:58
Fix a bug in the misc1 test script. (CVS 4526) (check-in: fa16996d99 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.429 2007/10/16 19:45:30 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.430 2007/11/05 15:30:13 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
          return rc;
        }
        releasePage(pFreePg);
      }while( nFin!=0 && iFreePg>nFin );
      assert( iFreePg<iLastPg );
      
      rc = sqlite3PagerWrite(pLastPg->pDbPage);
      if( rc!=SQLITE_OK ){
        return rc;
      } 
      rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg);
      releasePage(pLastPg);
      if( rc!=SQLITE_OK ){
        return rc;
      } 
    }
  }

  pBt->nTrunc = iLastPg - 1;
  while( pBt->nTrunc==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, pBt->nTrunc) ){
    pBt->nTrunc--;
  }







|
|
|
<



|







2164
2165
2166
2167
2168
2169
2170
2171
2172
2173

2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
          return rc;
        }
        releasePage(pFreePg);
      }while( nFin!=0 && iFreePg>nFin );
      assert( iFreePg<iLastPg );
      
      rc = sqlite3PagerWrite(pLastPg->pDbPage);
      if( rc==SQLITE_OK ){
        rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg);
      }

      releasePage(pLastPg);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }

  pBt->nTrunc = iLastPg - 1;
  while( pBt->nTrunc==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, pBt->nTrunc) ){
    pBt->nTrunc--;
  }
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.393 2007/10/20 13:17:55 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.394 2007/11/05 15:30:13 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056

4057
4058
4059
4060
4061
4062
4063
    if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
      if( (int)pPg->pgno <= pPager->origDbSize ){
        if( MEMDB ){
          PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
          PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqlite3_malloc( pPager->pageSize );
          if( pHist->pOrig ){
            memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
          }

        }else{
          u32 cksum;
          char *pData2;

          /* We should never write to the journal file the page that
          ** contains the database locks.  The following assert verifies
          ** that we do not. */







|
|

>







4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
    if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
      if( (int)pPg->pgno <= pPager->origDbSize ){
        if( MEMDB ){
          PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
          PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqlite3_malloc( pPager->pageSize );
          if( !pHist->pOrig ){
            return SQLITE_NOMEM;
          }
          memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
        }else{
          u32 cksum;
          char *pData2;

          /* We should never write to the journal file the page that
          ** contains the database locks.  The following assert verifies
          ** that we do not. */
Changes to test/malloc2.test.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file attempts to check that the library can recover from a malloc()
# failure when sqlite3_global_recover() is invoked.
#
# (Later:) The sqlite3_global_recover() interface is now a no-op.
# Recovery from malloc() failures is automatic.  But we keep these
# tests around because you can never have too many test cases.
#
# $Id: malloc2.test,v 1.8 2007/10/03 08:46:45 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
ifcapable !memdebug {







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file attempts to check that the library can recover from a malloc()
# failure when sqlite3_global_recover() is invoked.
#
# (Later:) The sqlite3_global_recover() interface is now a no-op.
# Recovery from malloc() failures is automatic.  But we keep these
# tests around because you can never have too many test cases.
#
# $Id: malloc2.test,v 1.9 2007/11/05 15:30:13 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
ifcapable !memdebug {
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
        puts "Error: $res"
      }
      set rc
    } {1}

    # If $::n is greater than the number of malloc() calls required to
    # execute the SQL, then this test is finished. Break out of the loop.
    set nFail [sqlite3_memdebug_fail -1]

    if {$nFail==0} break

    # Nothing should work now, because the allocator should refuse to
    # allocate any memory.
    #
    # Update: SQLite now automatically recovers from a malloc() failure.
    # So the statement in the test below would work. 







|
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
        puts "Error: $res"
      }
      set rc
    } {1}

    # If $::n is greater than the number of malloc() calls required to
    # execute the SQL, then this test is finished. Break out of the loop.
    set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign]
    incr nFail [expr {-1*$nBenign}]
    if {$nFail==0} break

    # Nothing should work now, because the allocator should refuse to
    # allocate any memory.
    #
    # Update: SQLite now automatically recovers from a malloc() failure.
    # So the statement in the test below would work. 
190
191
192
193
194
195
196
197


198
199
200
201
202
203
204
  do_test malloc2.3.setup {
    execsql {
      CREATE TEMP TABLE ghi(a, b, c);
      BEGIN;
    }
    for {set i 0} {$i<20} {incr i} {
      execsql {
      INSERT INTO ghi VALUES(randstr(300,300),randstr(300,300),randstr(300,300));


      }
    }
    execsql {
      COMMIT;
    }
  } {}
  do_malloc2_test 3 -sql {







|
>
>







191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  do_test malloc2.3.setup {
    execsql {
      CREATE TEMP TABLE ghi(a, b, c);
      BEGIN;
    }
    for {set i 0} {$i<20} {incr i} {
      execsql {
        INSERT INTO ghi VALUES(
            randstr(300,300), randstr(300,300), randstr(300,300)
        );
      }
    }
    execsql {
      COMMIT;
    }
  } {}
  do_malloc2_test 3 -sql {