1 2#pragma ident "%Z%%M% %I% %E% SMI" 3 4# 2001 September 15 5# 6# The author disclaims copyright to this source code. In place of 7# a legal notice, here is a blessing: 8# 9# May you do good and not evil. 10# May you find forgiveness for yourself and forgive others. 11# May you share freely, never taking more than you give. 12# 13#*********************************************************************** 14# This file attempts to check the library in an out-of-memory situation. 15# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special 16# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This 17# special feature is used to see what happens in the library if a malloc 18# were to really fail due to an out-of-memory situation. 19# 20# $Id: malloc.test,v 1.6 2004/02/14 01:39:50 drh Exp $ 21 22set testdir [file dirname $argv0] 23source $testdir/tester.tcl 24 25# Only run these tests if memory debugging is turned on. 26# 27if {[info command sqlite_malloc_stat]==""} { 28 puts "Skipping malloc tests: not compiled with -DMEMORY_DEBUG..." 29 finish_test 30 return 31} 32 33for {set go 1; set i 1} {$go} {incr i} { 34 do_test malloc-1.$i { 35 sqlite_malloc_fail 0 36 catch {db close} 37 catch {file delete -force test.db} 38 catch {file delete -force test.db-journal} 39 sqlite_malloc_fail $i 40 set v [catch {sqlite db test.db} msg] 41 if {$v} { 42 set msg "" 43 } else { 44 set v [catch {execsql { 45 CREATE TABLE t1( 46 a int, b float, c double, d text, e varchar(20), 47 primary key(a,b,c) 48 ); 49 CREATE INDEX i1 ON t1(a,b); 50 INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there'); 51 INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); 52 SELECT * FROM t1; 53 SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; 54 DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); 55 SELECT count(*) FROM t1; 56 }} msg] 57 } 58 set leftover [lindex [sqlite_malloc_stat] 2] 59 if {$leftover>0} { 60 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 61 set ::go 0 62 set v {1 1} 63 } else { 64 set v2 [expr {$msg=="" || $msg=="out of memory"}] 65 if {!$v2} {puts "\nError message returned: $msg"} 66 lappend v $v2 67 } 68 } {1 1} 69} 70 71set fd [open ./data.tmp w] 72for {set i 1} {$i<=20} {incr i} { 73 puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}] abcdefghijklmnopqrstuvwxyz" 74} 75close $fd 76 77for {set go 1; set i 1} {$go} {incr i} { 78 do_test malloc-2.$i { 79 sqlite_malloc_fail 0 80 catch {db close} 81 catch {file delete -force test.db} 82 catch {file delete -force test.db-journal} 83 sqlite_malloc_fail $i 84 set v [catch {sqlite db test.db} msg] 85 if {$v} { 86 set msg "" 87 } else { 88 set v [catch {execsql { 89 CREATE TABLE t1(a int, b int, c int); 90 CREATE INDEX i1 ON t1(a,b); 91 COPY t1 FROM 'data.tmp'; 92 SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; 93 UPDATE t1 SET b=b||b||b||b; 94 UPDATE t1 SET b=a WHERE a in (10,12,22); 95 INSERT INTO t1(c,b,a) VALUES(20,10,5); 96 INSERT INTO t1 SELECT * FROM t1 97 WHERE a IN (SELECT a FROM t1 WHERE a<10); 98 DELETE FROM t1 WHERE a>=10; 99 DROP INDEX i1; 100 DELETE FROM t1; 101 }} msg] 102 } 103 set leftover [lindex [sqlite_malloc_stat] 2] 104 if {$leftover>0} { 105 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 106 set ::go 0 107 set v {1 1} 108 } else { 109 set v2 [expr {$msg=="" || $msg=="out of memory"}] 110 if {!$v2} {puts "\nError message returned: $msg"} 111 lappend v $v2 112 } 113 } {1 1} 114} 115 116set fd [open ./data.tmp w] 117for {set i 1} {$i<=10} {incr i} { 118 puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]" 119} 120close $fd 121 122for {set go 1; set i 1} {$go} {incr i} { 123 do_test malloc-3.$i { 124 sqlite_malloc_fail 0 125 catch {db close} 126 catch {file delete -force test.db} 127 catch {file delete -force test.db-journal} 128 sqlite_malloc_fail $i 129 set v [catch {sqlite db test.db} msg] 130 if {$v} { 131 set msg "" 132 } else { 133 set v [catch {execsql { 134 BEGIN TRANSACTION; 135 CREATE TABLE t1(a int, b int, c int); 136 CREATE INDEX i1 ON t1(a,b); 137 COPY t1 FROM 'data.tmp'; 138 INSERT INTO t1(c,b,a) VALUES(20,10,5); 139 DELETE FROM t1 WHERE a>=10; 140 DROP INDEX i1; 141 DELETE FROM t1; 142 ROLLBACK; 143 }} msg] 144 } 145 set leftover [lindex [sqlite_malloc_stat] 2] 146 if {$leftover>0} { 147 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 148 set ::go 0 149 set v {1 1} 150 } else { 151 set v2 [expr {$msg=="" || $msg=="out of memory"}] 152 if {!$v2} {puts "\nError message returned: $msg"} 153 lappend v $v2 154 } 155 } {1 1} 156} 157for {set go 1; set i 1} {$go} {incr i} { 158 do_test malloc-4.$i { 159 sqlite_malloc_fail 0 160 catch {db close} 161 catch {file delete -force test.db} 162 catch {file delete -force test.db-journal} 163 sqlite_malloc_fail $i 164 set v [catch {sqlite db test.db} msg] 165 if {$v} { 166 set msg "" 167 } else { 168 set v [catch {execsql { 169 BEGIN TRANSACTION; 170 CREATE TABLE t1(a int, b int, c int); 171 CREATE INDEX i1 ON t1(a,b); 172 COPY t1 FROM 'data.tmp'; 173 UPDATE t1 SET b=a WHERE a in (10,12,22); 174 INSERT INTO t1 SELECT * FROM t1 175 WHERE a IN (SELECT a FROM t1 WHERE a<10); 176 DROP INDEX i1; 177 DELETE FROM t1; 178 COMMIT; 179 }} msg] 180 } 181 set leftover [lindex [sqlite_malloc_stat] 2] 182 if {$leftover>0} { 183 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 184 set ::go 0 185 set v {1 1} 186 } else { 187 set v2 [expr {$msg=="" || $msg=="out of memory"}] 188 if {!$v2} {puts "\nError message returned: $msg"} 189 lappend v $v2 190 } 191 } {1 1} 192} 193for {set go 1; set i 1} {$go} {incr i} { 194 do_test malloc-5.$i { 195 sqlite_malloc_fail 0 196 catch {db close} 197 catch {file delete -force test.db} 198 catch {file delete -force test.db-journal} 199 sqlite_malloc_fail $i 200 set v [catch {sqlite db test.db} msg] 201 if {$v} { 202 set msg "" 203 } else { 204 set v [catch {execsql { 205 BEGIN TRANSACTION; 206 CREATE TABLE t1(a,b); 207 CREATE TABLE t2(x,y); 208 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 209 INSERT INTO t2(x,y) VALUES(new.rowid,1); 210 END; 211 INSERT INTO t1(a,b) VALUES(2,3); 212 COMMIT; 213 }} msg] 214 } 215 set leftover [lindex [sqlite_malloc_stat] 2] 216 if {$leftover>0} { 217 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 218 set ::go 0 219 set v {1 1} 220 } else { 221 set v2 [expr {$msg=="" || $msg=="out of memory"}] 222 if {!$v2} {puts "\nError message returned: $msg"} 223 lappend v $v2 224 } 225 } {1 1} 226} 227sqlite_malloc_fail 0 228finish_test 229