• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 2007 Aug 13
2#
3# The author disclaims copyright to this source code.  In place of
4# a legal notice, here is a blessing:
5#
6#    May you do good and not evil.
7#    May you find forgiveness for yourself and forgive others.
8#    May you share freely, never taking more than you give.
9#
10#***********************************************************************
11#
12# This file tests aspects of the malloc failure while parsing
13# CREATE TABLE statements in auto_vacuum mode.
14#
15# $Id: mallocC.test,v 1.10 2009/04/11 16:27:50 drh Exp $
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19source $testdir/malloc_common.tcl
20
21# Only run these tests if memory debugging is turned on.
22#
23if {!$MEMDEBUG} {
24   puts "Skipping mallocC tests: not compiled with -DSQLITE_MEMDEBUG..."
25   finish_test
26   return
27}
28
29proc do_mallocC_test {tn args} {
30  array set ::mallocopts $args
31  #set sum [allcksum db]
32
33  for {set ::n 1} {true} {incr ::n} {
34
35    # Run the SQL. Malloc number $::n is set to fail. A malloc() failure
36    # may or may not be reported.
37    sqlite3_memdebug_fail $::n -repeat 1
38    do_test mallocC-$tn.$::n.1 {
39      set res [catchsql [string trim $::mallocopts(-sql)]]
40      set rc [expr {
41        0==[string compare $res {1 {out of memory}}] ||
42        [db errorcode] == 3082 ||
43        0==[lindex $res 0]
44      }]
45      if {$rc!=1} {
46        puts "Error: $res"
47      }
48      set rc
49    } {1}
50
51    # If $::n is greater than the number of malloc() calls required to
52    # execute the SQL, then this test is finished. Break out of the loop.
53    set nFail [sqlite3_memdebug_fail -1]
54    if {$nFail==0} {
55      break
56    }
57
58    # Recover from the malloc failure.
59    #
60    # Update: The new malloc() failure handling means that a transaction may
61    # still be active even if a malloc() has failed. But when these tests were
62    # written this was not the case. So do a manual ROLLBACK here so that the
63    # tests pass.
64    do_test mallocC-$tn.$::n.2 {
65      catch {
66        execsql {
67          ROLLBACK;
68        }
69      }
70      expr 0
71    } {0}
72
73    # Checksum the database.
74    #do_test mallocC-$tn.$::n.3 {
75    #  allcksum db
76    #} $sum
77
78    #integrity_check mallocC-$tn.$::n.4
79  }
80  unset ::mallocopts
81}
82
83sqlite3_extended_result_codes db 1
84
85execsql {
86  PRAGMA auto_vacuum=1;
87  CREATE TABLE t0(a, b, c);
88}
89
90# The number of memory allocation failures is different on 64-bit
91# and 32-bit systems due to larger structures on 64-bit systems
92# overflowing the lookaside more often.  To debug problems, it is
93# sometimes helpful to reduce the size of the lookaside allocation
94# blocks.  But this is normally disabled.
95#
96if {0} {
97  db close
98  sqlite3_shutdown
99  sqlite3_config_lookaside 50 500
100  sqlite3_initialize
101  autoinstall_test_functions
102  sqlite3 db test.db
103}
104
105do_mallocC_test 1 -sql {
106  BEGIN;
107  -- Allocate 32 new root pages. This will exercise the 'extract specific
108  -- page from the freelist' code when in auto-vacuum mode (see the
109  -- allocatePage() routine in btree.c).
110  CREATE TABLE t1(a UNIQUE, b UNIQUE, c UNIQUE);
111  CREATE TABLE t2(a UNIQUE, b UNIQUE, c UNIQUE);
112  CREATE TABLE t3(a UNIQUE, b UNIQUE, c UNIQUE);
113  CREATE TABLE t4(a UNIQUE, b UNIQUE, c UNIQUE);
114  CREATE TABLE t5(a UNIQUE, b UNIQUE, c UNIQUE);
115  CREATE TABLE t6(a UNIQUE, b UNIQUE, c UNIQUE);
116  CREATE TABLE t7(a UNIQUE, b UNIQUE, c UNIQUE);
117  CREATE TABLE t8(a UNIQUE, b UNIQUE, c UNIQUE);
118
119  ROLLBACK;
120}
121
122finish_test
123