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