Fix a couple of memory leaks in r-tree that can occur following an OOM condition.

FossilOrigin-Name: 1975a27cdec09e1dad4ca8281a87dd7754c02c3e
This commit is contained in:
dan 2010-08-26 14:15:37 +00:00
parent c23454023e
commit 897230eb7a
14 changed files with 89 additions and 82 deletions

View File

@ -2097,6 +2097,7 @@ static int deleteCell(Rtree *, RtreeNode *, int, int);
static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
int rc;
int rc2;
RtreeNode *pParent;
int iCell;
@ -2106,9 +2107,12 @@ static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
iCell = nodeParentIndex(pRtree, pNode);
pParent = pNode->pParent;
pNode->pParent = 0;
if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1))
|| SQLITE_OK!=(rc = nodeRelease(pRtree, pParent))
){
rc = deleteCell(pRtree, pParent, iCell, iHeight+1);
rc2 = nodeRelease(pRtree, pParent);
if( rc==SQLITE_OK ){
rc = rc2;
}
if( rc!=SQLITE_OK ){
return rc;
}
@ -2448,12 +2452,15 @@ static int rtreeUpdate(
** in this scenario).
*/
if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
int rc2;
RtreeNode *pChild;
i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
if( rc==SQLITE_OK ){
rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
}
rc2 = nodeRelease(pRtree, pChild);
if( rc==SQLITE_OK ) rc = rc2;
if( rc==SQLITE_OK ){
pRtree->iDepth--;
writeInt16(pRoot->zData, pRtree->iDepth);

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

View File

@ -14,26 +14,39 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !rtree {
finish_test
return
}
# Only run these tests if memory debugging is turned on.
# Test summary:
#
# rtree3-1: Test OOM in simple CREATE TABLE, INSERT, DELETE and SELECT
# commands on an almost empty table.
#
# rtree3-2: Test OOM in a DROP TABLE command.
#
# rtree3-3a: Test OOM during a transaction to insert 100 pseudo-random rows.
#
# rtree3-3b: Test OOM during a transaction deleting all entries in the
# database constructed in [rtree3-3a] in pseudo-random order.
#
# rtree3-4a: OOM during "SELECT count(*) FROM ..." on a big table.
#
# rtree3-4b: OOM while deleting rows from a big table.
#
# rtree3-5: Test OOM while inserting rows into a big table.
#
# rtree3-6: Test OOM while deleting all rows of a table, one at a time.
#
# rtree3-7: OOM during an ALTER TABLE RENAME TABLE command.
#
# rtree3-8: Test OOM while registering the r-tree module with sqlite.
#
source $testdir/malloc_common.tcl
if {!$MEMDEBUG} {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test
return
}
if 1 {
do_faultsim_test rtree3-1 -faults oom* -prep {
faultsim_delete_and_reopen
@ -96,8 +109,6 @@ do_faultsim_test rtree3-3b -faults oom* -prep {
db eval COMMIT
}
}
do_test rtree3-4.prep {
faultsim_delete_and_reopen
execsql {
@ -120,7 +131,7 @@ do_faultsim_test rtree3-4a -faults oom-* -prep {
faultsim_test_result {0 1500}
}
do_faultsim_test rtree3-4b -faults oom-* -prep {
do_faultsim_test rtree3-4b -faults oom-transient -prep {
faultsim_restore_and_reopen
} -body {
db eval { DELETE FROM rt WHERE ii BETWEEN 1 AND 100 }

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
@ -93,7 +93,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
for {set i 1} {$i<$::NROW} {incr i} {
# Do a random insert
#
do_test rtree-$nDim.2.$i.1 {
do_test rtree4-$nDim.2.$i.1 {
set vlist {}
for {set j 0} {$j<$nDim} {incr j} {
set mn [rand 10000]
@ -113,7 +113,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=$mn mx$j<=$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.2 {
do_test rtree4-$nDim.2.$i.2 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -126,7 +126,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>=$mn mn$j<=$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.3 {
do_test rtree4-$nDim.2.$i.3 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -143,7 +143,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=$mn mx$j<=$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.3 {
do_test rtree4-$nDim.2.$i.3 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -160,7 +160,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>$mn mn$j<$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.4 {
do_test rtree4-$nDim.2.$i.4 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -176,7 +176,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=-10000 mx$j<10000
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.5 {
do_test rtree4-$nDim.2.$i.5 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -192,7 +192,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>-10000 mn$j<=10000
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.6 {
do_test rtree4-$nDim.2.$i.6 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -208,7 +208,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=$mn1 mn$j>$mn2 mx$j<$mx1 mx$j<=$mx2
}
set where "WHERE [join [scramble $where] { AND }]"
do_test rtree-$nDim.2.$i.7 {
do_test rtree4-$nDim.2.$i.7 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -224,7 +224,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>=$mn1 mx$j>$mn2 mn$j<$mx1 mn$j<=$mx2
}
set where "WHERE [join [scramble $where] { AND }]"
do_test rtree-$nDim.2.$i.8 {
do_test rtree4-$nDim.2.$i.8 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
}

View File

@ -14,7 +14,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl

View File

@ -12,7 +12,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl

View File

@ -15,7 +15,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl

View File

@ -12,7 +12,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
ifcapable !rtree { finish_test ; return }

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

View File

@ -1,5 +1,5 @@
C Remove\sunreachable\scondition\sfrom\srtree.c.
D 2010-08-26T11:27:23
C Fix\sa\scouple\sof\smemory\sleaks\sin\sr-tree\sthat\scan\soccur\sfollowing\san\sOOM\scondition.
D 2010-08-26T14:15:38
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 543f91f24cd7fee774ecc0a61c19704c0c3e78fd
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -78,19 +78,19 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c 850e9a36567bbcce6bd85a4b68243cad8e3c2de2
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 536070b23d6da289824460a08529f07e638d7c81
F ext/rtree/rtree.c 2e87d4f44329bfdfb1d074d874b7500e9db83a06
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 51bb0cd0405970501e63258401ae5ad235a4f468
F ext/rtree/rtree2.test 47b90f549a59e667e9fb01338956ead6f66c8d9d
F ext/rtree/rtree3.test db7652535e339bbbf5f3909599a088c7daa4be87
F ext/rtree/rtree4.test 2adce44dc544f6eb570898c8d5270bdf6ca64bd8
F ext/rtree/rtree5.test 92508f5152a50110af6551fa5b769d1bbd7c4ef3
F ext/rtree/rtree6.test 903720aaab819764c3693aaac0affe8174104ac8
F ext/rtree/rtree7.test 6fd29fb8e13795c822f4ceeea92ab5d61c96976d
F ext/rtree/rtree8.test 64b83b163a6997202e11c4226a74e7e52f26e75c
F ext/rtree/rtree1.test dbd4250ac0ad367a262eb9676f7e3080b0368206
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
F ext/rtree/rtree3.test deafc076f639b824466e9f82b39f1601b86dca8e
F ext/rtree/rtree4.test 0061e6f464fd3dc6a79f82454c5a1c3dadbe42af
F ext/rtree/rtree5.test ce3d7ccae2cfd9d2e1052b462424964c9bdcda12
F ext/rtree/rtree6.test 1ebe0d632a7501cc80ba5a225f028fd4f0fdda08
F ext/rtree/rtree7.test bcb647b42920b3b5d025846689147778485cc318
F ext/rtree/rtree8.test e4e291e4cdbc576ac0cfc34c6a75c00b2ee347c3
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/tkt3363.test 2bf324f7908084a5f463de3109db9c6e607feb1b
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
@ -550,7 +550,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test 17498d1219f922d5a6da893a94c4dc7766fb2426
F test/permutations.test fff338765bb6d9235d385ead4e6d5c9433b6ba05
F test/pragma.test ed78d200f65c6998df51196cb8c39d5300570f24
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
@ -565,7 +565,7 @@ F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/rollback.test 1a83118ea6db4e7d8c10eaa63871b5e90502ffdc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test e58e0acef38b527ed1b0b70d3ada588f804af287
F test/rtree.test dbc0c5113c1d67e5cc44a495d682dda531c83fd4
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
F test/savepoint.test 992d6429b6bce16ac172f7431975044ceaeb0803
F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec
@ -847,7 +847,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P bee1959dde19ebec20a7ffcb732aee0c8bb2e67d
R 9fb046de4a8191bdd0781857213d3e87
P 90f40cd36860d3af13ec24575dff7cc1f57ac493
R a46858ce791434a7e43a1a791bfcb584
U dan
Z 921a91bcff15deea1dac40ed4f714457
Z 87e2b951218964ab648d9c5a5a463f97

View File

@ -1 +1 @@
90f40cd36860d3af13ec24575dff7cc1f57ac493
1975a27cdec09e1dad4ca8281a87dd7754c02c3e

View File

@ -69,6 +69,7 @@ proc test_set {args} {
foreach f $a { set t($f) 1 }
} else {
foreach f $a { array unset t $f }
foreach f $a { array unset t */$f }
}
}
@ -84,13 +85,17 @@ proc test_set {args} {
#
set alltests [list]
foreach f [glob $testdir/*.test] { lappend alltests [file tail $f] }
foreach f [glob -nocomplain $testdir/../ext/rtree/*.test] {
lappend alltests $f
}
if {$::tcl_platform(platform)!="unix"} {
set alltests [test_set $alltests -exclude crash.test crash2.test]
}
set alltests [test_set $alltests -exclude {
all.test async.test quick.test veryquick.test
memleak.test permutations.test soak.test fts3.test
mallocAll.test
mallocAll.tes rtree.test
}]
set allquicktests [test_set $alltests -exclude {
@ -105,7 +110,7 @@ set allquicktests [test_set $alltests -exclude {
thread003.test thread004.test thread005.test trans2.test vacuum3.test
incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
vtab_err.test walslow.test walcrash.test
walthread.test
walthread.test rtree3.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
@ -734,6 +739,11 @@ test_suite "wal" -description {
fts3am.test fts3an.test fts3ao.test fts3b.test
fts3c.test fts3d.test fts3e.test fts3query.test
}
test_suite "rtree" -description {
All R-tree related tests. Provides coverage of source file rtree.c.
} -files [glob -nocomplain $::testdir/../ext/rtree/*.test]
# End of tests
#############################################################################
@ -759,7 +769,8 @@ proc run_tests {name args} {
uplevel $options(-initialize)
foreach file [lsort $options(-files)] {
slave_test_file $::testdir/$file
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
slave_test_file $file
}
uplevel $options(-shutdown)

View File

@ -1,3 +1,4 @@
# 2008 June 23
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
@ -6,35 +7,12 @@
#***********************************************************************
# This file runs all rtree related tests.
#
# $Id: rtree.test,v 1.3 2009/05/25 14:17:35 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/permutations.test
rename finish_test rtree_finish_test
proc finish_test {} {}
set RTREE_EXCLUDE { }
if {[info exists G(isquick)] && $G(isquick)} {
set RTREE_EXCLUDE rtree3.test
}
set G(isquick) 1
set rtreedir [file join $testdir .. ext rtree]
foreach testfile [lsort -dictionary [glob -nocomplain $rtreedir/*.test]] {
set tail [file tail $testfile]
if {[lsearch -exact $RTREE_EXCLUDE $tail]>=0} continue
source $testfile
catch {db close}
if {$sqlite_open_file_count>0} {
puts "$tail did not close all files: $sqlite_open_file_count"
fail_test $tail
set sqlite_open_file_count 0
}
ifcapable rtree {
run_test_suite rtree
}
set sqlite_open_file_count 0
rtree_finish_test
rename finish_test {}
rename rtree_finish_test finish_test
finish_test