SQLite

Check-in [046ef07261]
Login

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

Overview
Comment:Always transform error code SQLITE_IOERR_NOMEM to SQLITE_NOMEM before returning. This was already happening in most places. (CVS 5738)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 046ef07261d520c9399bd8cdfdfd5281956b7a27
User & Date: danielk1977 2008-09-23 16:41:30.000
Context
2008-09-23
17:39
Catch another case where SQLITE_IOERR could be returned instead of SQLITE_NOMEM following an out-of-memory error. (CVS 5739) (check-in: 18d030da0c user: danielk1977 tags: trunk)
16:41
Always transform error code SQLITE_IOERR_NOMEM to SQLITE_NOMEM before returning. This was already happening in most places. (CVS 5738) (check-in: 046ef07261 user: danielk1977 tags: trunk)
10:23
Enable the LOCKING_STYLE extensions by default on a Mac. Leave them disabled on all other posix platforms. (CVS 5737) (check-in: bae1d5b169 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/malloc.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
**
** $Id: malloc.c,v 1.41 2008/09/04 04:32:49 shane Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** This routine runs when the memory allocator sees that the







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
**
** $Id: malloc.c,v 1.42 2008/09/23 16:41:30 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** This routine runs when the memory allocator sees that the
748
749
750
751
752
753
754
755
756
757
758
759
760
761
*/
int sqlite3ApiExit(sqlite3* db, int rc){
  /* If the db handle is not NULL, then we must hold the connection handle
  ** mutex here. Otherwise the read (and possible write) of db->mallocFailed 
  ** is unsafe, as is the call to sqlite3Error().
  */
  assert( !db || sqlite3_mutex_held(db->mutex) );
  if( db && db->mallocFailed ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
    db->mallocFailed = 0;
    rc = SQLITE_NOMEM;
  }
  return rc & (db ? db->errMask : 0xff);
}







|






748
749
750
751
752
753
754
755
756
757
758
759
760
761
*/
int sqlite3ApiExit(sqlite3* db, int rc){
  /* If the db handle is not NULL, then we must hold the connection handle
  ** mutex here. Otherwise the read (and possible write) of db->mallocFailed 
  ** is unsafe, as is the call to sqlite3Error().
  */
  assert( !db || sqlite3_mutex_held(db->mutex) );
  if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
    db->mallocFailed = 0;
    rc = SQLITE_NOMEM;
  }
  return rc & (db ? db->errMask : 0xff);
}
Changes to src/os.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains OS interface code that is common to all
** architectures.
**
** $Id: os.c,v 1.122 2008/09/02 17:18:52 danielk1977 Exp $
*/
#define _SQLITE_OS_C_ 1
#include "sqliteInt.h"
#undef _SQLITE_OS_C_

/*
** The default SQLite sqlite3_vfs implementations do not allocate







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains OS interface code that is common to all
** architectures.
**
** $Id: os.c,v 1.123 2008/09/23 16:41:30 danielk1977 Exp $
*/
#define _SQLITE_OS_C_ 1
#include "sqliteInt.h"
#undef _SQLITE_OS_C_

/*
** The default SQLite sqlite3_vfs implementations do not allocate
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
**     sqlite3OsOpen()
**     sqlite3OsRead()
**     sqlite3OsWrite()
**     sqlite3OsSync()
**     sqlite3OsLock()
**
*/
#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) && 0
  #define DO_OS_MALLOC_TEST if (1) {            \
    void *pTstAlloc = sqlite3Malloc(10);       \
    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
    sqlite3_free(pTstAlloc);                    \
  }
#else
  #define DO_OS_MALLOC_TEST







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
**     sqlite3OsOpen()
**     sqlite3OsRead()
**     sqlite3OsWrite()
**     sqlite3OsSync()
**     sqlite3OsLock()
**
*/
#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
  #define DO_OS_MALLOC_TEST if (1) {            \
    void *pTstAlloc = sqlite3Malloc(10);       \
    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
    sqlite3_free(pTstAlloc);                    \
  }
#else
  #define DO_OS_MALLOC_TEST
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.493 2008/09/19 09:14:44 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/







|







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.494 2008/09/23 16:41:30 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
          pPager->journalOff = szJ;
          break;
        }else{
          /* If we are unable to rollback, then the database is probably
          ** going to end up being corrupt.  It is corrupt to us, anyhow.
          ** Perhaps the next process to come along can fix it....
          */
          rc = SQLITE_CORRUPT;
          goto end_playback;
        }
      }
    }
  }
  /*NOTREACHED*/
  assert( 0 );







|







1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
          pPager->journalOff = szJ;
          break;
        }else{
          /* If we are unable to rollback, then the database is probably
          ** going to end up being corrupt.  It is corrupt to us, anyhow.
          ** Perhaps the next process to come along can fix it....
          */
          rc = SQLITE_CORRUPT_BKPT;
          goto end_playback;
        }
      }
    }
  }
  /*NOTREACHED*/
  assert( 0 );
Changes to test/malloc.test.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.66 2008/09/22 17:22:20 danielk1977 Exp $

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


# Only run these tests if memory debugging is turned on.
#







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file attempts to check the behavior of the SQLite library in 
# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 
# the SQLite library accepts a special command (sqlite3_memdebug_fail N C)
# which causes the N-th malloc to fail.  This special feature is used
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.67 2008/09/23 16:41:30 danielk1977 Exp $

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


# Only run these tests if memory debugging is turned on.
#
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Do a couple of memory dumps just to exercise the memory dump logic
# that that we can say that we have.
#
puts stderr "This is a test.  Ignore the error that follows:"
sqlite3_memdebug_dump $testdir
puts "Memory dump to file memdump.txt..."
sqlite3_memdebug_dump memdump.txt


ifcapable bloblit&&subquery {
  do_malloc_test 1 -tclprep {
    db close
  } -tclbody {
    if {[catch {sqlite3 db test.db}]} {
      error "out of memory"







<







34
35
36
37
38
39
40

41
42
43
44
45
46
47
# Do a couple of memory dumps just to exercise the memory dump logic
# that that we can say that we have.
#
puts stderr "This is a test.  Ignore the error that follows:"
sqlite3_memdebug_dump $testdir
puts "Memory dump to file memdump.txt..."
sqlite3_memdebug_dump memdump.txt


ifcapable bloblit&&subquery {
  do_malloc_test 1 -tclprep {
    db close
  } -tclbody {
    if {[catch {sqlite3 db test.db}]} {
      error "out of memory"
342
343
344
345
346
347
348
349
350
351







352
353
354
355
356
357
358
    }
    copy_file test2.db test.db
    copy_file test2.db-journal test.db-journal
    db2 close
  } -tclbody {
    sqlite3 db test.db
    sqlite3_extended_result_codes db 1
    db eval {
      SELECT * FROM t1;
    }  







  }
}

proc string_compare {a b} {
  return [string compare $a $b]
}








<
<
|
>
>
>
>
>
>
>







341
342
343
344
345
346
347


348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
    }
    copy_file test2.db test.db
    copy_file test2.db-journal test.db-journal
    db2 close
  } -tclbody {
    sqlite3 db test.db
    sqlite3_extended_result_codes db 1



    # If an out-of-memory occurs within a call to a VFS layer function during
    # hot-journal rollback, sqlite will report SQLITE_CORRUPT. See commit
    # [5668] for details.
    set rc [catch {db eval { SELECT * FROM t1 }} msg]
    if {$msg eq "database disk image is malformed"} { set msg "out of memory" }
    if {$rc} { error $msg }
    set msg
  }
}

proc string_compare {a b} {
  return [string compare $a $b]
}

564
565
566
567
568
569
570
571



572



573
574
575
576
577
578
579
    # This puts the pager into error state.
    #
    db eval BEGIN
    db eval {UPDATE abc SET a = 0 WHERE oid%2}
    set ::sqlite_io_error_pending 10
    catch {db eval {ROLLBACK}} msg

  } -sqlbody {



    SELECT * FROM abc LIMIT 10;



  } -cleanup {
    set e [db eval {PRAGMA integrity_check}]
    if {$e ne "ok"} {error $e}
  }
}

ifcapable compound {







|
>
>
>
|
>
>
>







568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
    # This puts the pager into error state.
    #
    db eval BEGIN
    db eval {UPDATE abc SET a = 0 WHERE oid%2}
    set ::sqlite_io_error_pending 10
    catch {db eval {ROLLBACK}} msg

  } -tclbody {
    # If an out-of-memory occurs within a call to a VFS layer function during
    # hot-journal rollback, sqlite will report SQLITE_CORRUPT. See commit
    # [5668] for details.
    set rc [catch {db eval { SELECT * FROM abc LIMIT 10 }} msg]
    if {$msg eq "database disk image is malformed"} { set msg "out of memory" }
    if {$rc} { error $msg }
    set msg
  } -cleanup {
    set e [db eval {PRAGMA integrity_check}]
    if {$e ne "ok"} {error $e}
  }
}

ifcapable compound {
Changes to test/malloc_common.tcl.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.21 2008/08/04 20:13:27 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable builtin_test {
  set MEMDEBUG 1
} else {
  set MEMDEBUG 0







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.22 2008/09/23 16:41:30 danielk1977 Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable builtin_test {
  set MEMDEBUG 1
} else {
  set MEMDEBUG 0
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
            set v2 1
          }
        } elseif {!$isFail} {
          set v2 $msg
        } elseif {
          [info command db]=="" || 
          [db errorcode]==7 ||
          [db errorcode]==[expr 10+(12<<8)] ||
          $msg=="out of memory"
        } {
          set v2 1
        } else {
          set v2 $msg
          puts [db errorcode]
        }







<







143
144
145
146
147
148
149

150
151
152
153
154
155
156
            set v2 1
          }
        } elseif {!$isFail} {
          set v2 $msg
        } elseif {
          [info command db]=="" || 
          [db errorcode]==7 ||

          $msg=="out of memory"
        } {
          set v2 1
        } else {
          set v2 $msg
          puts [db errorcode]
        }