From: drh Date: Mon, 13 Aug 2007 12:39:03 +0000 (+0000) Subject: Add a new test cases for a problem with malloc failure during the parsing X-Git-Tag: version-3.6.10~1963 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b3226e857c0eeb809d51d7f5db72fd7944cb175a;p=thirdparty%2Fsqlite.git Add a new test cases for a problem with malloc failure during the parsing of CREATE TABLE statements in autovacuum mode. (CVS 4211) FossilOrigin-Name: be50387e658a9a73e12b07ca89ae75e871489f16 --- diff --git a/manifest b/manifest index 6b5559cd87..14a40ae9fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\smemory\sallocation\sfrom\ssqlite3VdbeIOTraceSql().\s\sThis\smeans\sthat\nwhen\sdoing\sI/O\stracing,\sthe\stext\sof\san\sSQL\sstatement\sis\struncated\sto\sthe\nfirst\s1000\scharacters.\s\sBut\sit\salso\smeans\stracing\sworks\sin\san\sout-of-memory\nsituation.\s(CVS\s4210) -D 2007-08-13T11:10:35 +C Add\sa\snew\stest\scases\sfor\sa\sproblem\swith\smalloc\sfailure\sduring\sthe\sparsing\nof\sCREATE\sTABLE\sstatements\sin\sautovacuum\smode.\s(CVS\s4211) +D 2007-08-13T12:39:04 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -315,6 +315,7 @@ F test/malloc8.test e4054ca2a87ab1d42255bec009b177ba20b5a487 F test/malloc9.test 8381041fd89c31fba60c8a1a1c776bb022108572 F test/mallocA.test 525674e6e0775a9bf85a33f1da1c6bbddc712c30 F test/mallocB.test 5d4a3dc4931a8c13ef3723c4934af23ff9d60d71 +F test/mallocC.test 7aea2854b3b4e594d2b4c032490e81440c2c4643 F test/malloc_common.tcl 3cda97d63fbf370061ffa9795a24e5027367fef3 F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8 F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893 @@ -524,7 +525,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 990f621f2247f1636e895dcf51fea1e08f202d31 -R 0fa9df43f865850ecc78db80fef1138d +P 578da2476e356ea35d272e18faf490efedeaf25c +R 281d69a5cf894aa6aa42abf77097453b U drh -Z 94518ffb3c3b64a4210e21c75b2f41f5 +Z a2e5e44543994276bad6f982b551b91d diff --git a/manifest.uuid b/manifest.uuid index 687bb9ce95..09252a6d4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -578da2476e356ea35d272e18faf490efedeaf25c \ No newline at end of file +be50387e658a9a73e12b07ca89ae75e871489f16 \ No newline at end of file diff --git a/test/mallocC.test b/test/mallocC.test new file mode 100644 index 0000000000..d2545def3a --- /dev/null +++ b/test/mallocC.test @@ -0,0 +1,131 @@ +# 2007 Aug 13 +# +# 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. +# +#*********************************************************************** +# +# This file tests aspects of the malloc failure while parsing +# CREATE TABLE statements in auto_vacuum mode. +# +# $Id: mallocC.test,v 1.1 2007/08/13 12:39:04 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Only run these tests if memory debugging is turned on. +# +if {[info command sqlite_malloc_stat]==""} { + puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG=1" + finish_test + return +} + +# Generate a checksum based on the contents of the database. If the +# checksum of two databases is the same, and the integrity-check passes +# for both, the two databases are identical. +# +proc cksum {db} { + set ret [list] + ifcapable tempdb { + set sql { + SELECT name FROM sqlite_master WHERE type = 'table' UNION + SELECT name FROM sqlite_temp_master WHERE type = 'table' UNION + SELECT 'sqlite_master' UNION + SELECT 'sqlite_temp_master' + } + } else { + set sql { + SELECT name FROM sqlite_master WHERE type = 'table' UNION + SELECT 'sqlite_master' + } + } + set tbllist [$db eval $sql] + set txt {} + foreach tbl $tbllist { + append txt [$db eval "SELECT * FROM $tbl"] + } + # puts txt=$txt + return [md5 $txt] +} + +proc do_mallocC_test {tn args} { + array set ::mallocopts $args + set sum [cksum db] + + for {set ::n 1} {true} {incr ::n} { + + # Run the SQL. Malloc number $::n is set to fail. A malloc() failure + # may or may not be reported. + sqlite_malloc_fail $::n + do_test malloc2shl-$tn.$::n.1 { + set res [catchsql [string trim $::mallocopts(-sql)]] + set rc [expr { + 0==[string compare $res {1 {out of memory}}] || + 0==[lindex $res 0] + }] + if {$rc!=1} { + 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. + if {[lindex [sqlite_malloc_stat] 2]>0} { + sqlite_malloc_fail -1 + break + } + + # Recover from the malloc failure. + # + # Update: The new malloc() failure handling means that a transaction may + # still be active even if a malloc() has failed. But when these tests were + # written this was not the case. So do a manual ROLLBACK here so that the + # tests pass. + do_test malloc2shl-$tn.$::n.2 { + catch { + execsql { + ROLLBACK; + } + } + expr 0 + } {0} + + # Checksum the database. + #do_test malloc2shl-$tn.$::n.3 { + # cksum db + #} $sum + + #integrity_check malloc2shl-$tn.$::n.4 + if {$::nErr>1} return + } + unset ::mallocopts +} + +execsql { + PRAGMA auto_vacuum=1; + CREATE TABLE t0(a, b, c); +} +do_mallocC_test 1 -sql { + BEGIN; + -- Allocate 32 new root pages. This will exercise the 'extract specific + -- page from the freelist' code when in auto-vacuum mode (see the + -- allocatePage() routine in btree.c). + CREATE TABLE t1(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t2(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t3(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t4(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t5(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t6(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t7(a UNIQUE, b UNIQUE, c UNIQUE); + CREATE TABLE t8(a UNIQUE, b UNIQUE, c UNIQUE); + + ROLLBACK; +} + +finish_test