1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Avoid leaking page references after an IO error is encountered. (CVS 5082)

FossilOrigin-Name: 198c395b01140ef48b6913c00188ba7168bfb081
This commit is contained in:
danielk1977
2008-05-05 15:26:50 +00:00
parent 344c38e340
commit 4abd5449e8
5 changed files with 43 additions and 34 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sa\scouple\sof\sminor\sproblems\swith\stransactions\sin\svirtual\stables.\s(CVS\s5081) C Avoid\sleaking\spage\sreferences\safter\san\sIO\serror\sis\sencountered.\s(CVS\s5082)
D 2008-05-05T13:23:04 D 2008-05-05T15:26:51
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -86,7 +86,7 @@ F src/attach.c 496cc628b2e8c4d8db99d7c136761fcbebd8420b
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/bitvec.c 8ec2212cfb702bc4f402c0b7ae7623d85320c714 F src/bitvec.c 8ec2212cfb702bc4f402c0b7ae7623d85320c714
F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
F src/btree.c 6b16a43adb8f8c62b6344f5f364ead46b77e4cc6 F src/btree.c 638f450da27c3f66ad081aae6888dc1961f76fc5
F src/btree.h 8826591bf54dd35fcf2e67473d5f1bae253861c7 F src/btree.h 8826591bf54dd35fcf2e67473d5f1bae253861c7
F src/btreeInt.h dc04ee33d8eb84714b2acdf81336fbbf6e764530 F src/btreeInt.h dc04ee33d8eb84714b2acdf81336fbbf6e764530
F src/build.c a52d9d51341444a2131e3431608f245db80d9591 F src/build.c a52d9d51341444a2131e3431608f245db80d9591
@@ -342,7 +342,7 @@ F test/insert5.test 509017213328147d3acdfa2c441bfd82362dda41
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
F test/io.test 833a1746518ec3005aa7792f9bcb8f01923ff544 F test/io.test 833a1746518ec3005aa7792f9bcb8f01923ff544
F test/ioerr.test 5382046b2ef19b9084652e7d2d1e82ab33c0deda F test/ioerr.test 32cff40562447bda194ba67ad601170edbaed49b
F test/ioerr2.test b9c9a0491a812707762a7c002876553be54d9969 F test/ioerr2.test b9c9a0491a812707762a7c002876553be54d9969
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/join.test af0443185378b64878750aa1cf4b83c216f246b4 F test/join.test af0443185378b64878750aa1cf4b83c216f246b4
@@ -458,7 +458,7 @@ F test/tableapi.test 791f7e3891d9b70bdb43b311694bf5e9befcbc34
F test/tclsqlite.test 3dfb48f46de4353376fad835390b493ba066b4dc F test/tclsqlite.test 3dfb48f46de4353376fad835390b493ba066b4dc
F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1 F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125 F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
F test/tester.tcl 72e180cc91fae17fd6ea43d1cd84558421105b72 F test/tester.tcl 3f476ad2a7d8532b8de3ad7b0ed95995ee78f45b
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7 F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
@@ -634,7 +634,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 270d47e8d0a20868879a95b66cb547e1e5b642d9 P 2275fc6ee06b17da5808cecfa5570ac6439eaf74
R 384696721267b63cda5341ca180b7b1f R 6d76420da4b019df82bc43b649a5cfb1
U drh U danielk1977
Z 11a335d880f2acd480b0e07b2674209e Z 562dc8fb914e4c15e377eee1cc4d777b

View File

@@ -1 +1 @@
2275fc6ee06b17da5808cecfa5570ac6439eaf74 198c395b01140ef48b6913c00188ba7168bfb081

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** May you share freely, never taking more than you give.
** **
************************************************************************* *************************************************************************
** $Id: btree.c,v 1.454 2008/05/05 12:09:33 danielk1977 Exp $ ** $Id: btree.c,v 1.455 2008/05/05 15:26:51 danielk1977 Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information. ** See the header comment on "btreeInt.h" for additional information.
@@ -6835,16 +6835,12 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){
** present in pTo before the copy operation, journal page i from pTo. ** present in pTo before the copy operation, journal page i from pTo.
*/ */
if( i!=iSkip && i<=nToPage ){ if( i!=iSkip && i<=nToPage ){
DbPage *pDbPage; DbPage *pDbPage = 0;
rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage); rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage);
if( rc ){ if( rc==SQLITE_OK ){
break;
}
rc = sqlite3PagerWrite(pDbPage); rc = sqlite3PagerWrite(pDbPage);
if( rc ){
break;
} }
if( i>nFromPage ){ if( rc==SQLITE_OK && i>nFromPage ){
/* Yeah. It seems wierd to call DontWrite() right after Write(). But /* Yeah. It seems wierd to call DontWrite() right after Write(). But
** that is because the names of those procedures do not exactly ** that is because the names of those procedures do not exactly
** represent what they do. Write() really means "put this page in the ** represent what they do. Write() really means "put this page in the

View File

@@ -15,12 +15,11 @@
# The tests in this file use special facilities that are only # The tests in this file use special facilities that are only
# available in the SQLite test fixture. # available in the SQLite test fixture.
# #
# $Id: ioerr.test,v 1.34 2008/01/16 17:46:38 drh Exp $ # $Id: ioerr.test,v 1.35 2008/05/05 15:26:51 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error
# on the 8th IO operation in the SQL script below doesn't report an error. # on the 8th IO operation in the SQL script below doesn't report an error.
# #
@@ -28,7 +27,7 @@ source $testdir/tester.tcl
# file when the file on disk is only 1 page. The pager layer detects that # file when the file on disk is only 1 page. The pager layer detects that
# this has happened and suppresses the error returned by the OS layer. # this has happened and suppresses the error returned by the OS layer.
# #
do_ioerr_test ioerr-1 -erc 1 -sqlprep { do_ioerr_test ioerr-1 -erc 1 -ckrefcount 1 -sqlprep {
SELECT * FROM sqlite_master; SELECT * FROM sqlite_master;
} -sqlbody { } -sqlbody {
CREATE TABLE t1(a,b,c); CREATE TABLE t1(a,b,c);
@@ -56,7 +55,7 @@ do_ioerr_test ioerr-1 -erc 1 -sqlprep {
# detected. Same reason as the 8th in the test case above. # detected. Same reason as the 8th in the test case above.
# #
ifcapable vacuum { ifcapable vacuum {
do_ioerr_test ioerr-2 -cksum true -sqlprep { do_ioerr_test ioerr-2 -cksum true -ckrefcount true -sqlprep {
BEGIN; BEGIN;
CREATE TABLE t1(a, b, c); CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, randstr(50,50), randstr(50,50)); INSERT INTO t1 VALUES(1, randstr(50,50), randstr(50,50));
@@ -78,7 +77,7 @@ ifcapable vacuum {
1 [expr [string match [execsql {pragma auto_vacuum}] 1]?9:-1]] 1 [expr [string match [execsql {pragma auto_vacuum}] 1]?9:-1]]
} }
do_ioerr_test ioerr-3 -tclprep { do_ioerr_test ioerr-3 -ckrefcount true -tclprep {
execsql { execsql {
PRAGMA cache_size = 10; PRAGMA cache_size = 10;
BEGIN; BEGIN;
@@ -102,7 +101,7 @@ do_ioerr_test ioerr-3 -tclprep {
# Test IO errors that can occur retrieving a record header that flows over # Test IO errors that can occur retrieving a record header that flows over
# onto an overflow page. # onto an overflow page.
do_ioerr_test ioerr-4 -tclprep { do_ioerr_test ioerr-4 -ckrefcount true -tclprep {
set sql "CREATE TABLE abc(a1" set sql "CREATE TABLE abc(a1"
for {set i 2} {$i<1300} {incr i} { for {set i 2} {$i<1300} {incr i} {
append sql ", a$i" append sql ", a$i"
@@ -123,7 +122,7 @@ ifcapable attach {
if {[string match [execsql {pragma auto_vacuum}] 1]} { if {[string match [execsql {pragma auto_vacuum}] 1]} {
set ex [list 4 17] set ex [list 4 17]
} }
do_ioerr_test ioerr-5 -sqlprep { do_ioerr_test ioerr-5 -ckrefcount true -sqlprep {
ATTACH 'test2.db' AS test2; ATTACH 'test2.db' AS test2;
} -sqlbody { } -sqlbody {
BEGIN; BEGIN;
@@ -137,7 +136,7 @@ ifcapable attach {
# transaction. This test only runs on UNIX. # transaction. This test only runs on UNIX.
ifcapable crashtest&&attach { ifcapable crashtest&&attach {
if {![catch {sqlite3 -has_codec} r] && !$r} { if {![catch {sqlite3 -has_codec} r] && !$r} {
do_ioerr_test ioerr-6 -tclprep { do_ioerr_test ioerr-6 -ckrefcount true -tclprep {
execsql { execsql {
ATTACH 'test2.db' as aux; ATTACH 'test2.db' as aux;
CREATE TABLE tx(a, b); CREATE TABLE tx(a, b);
@@ -193,7 +192,7 @@ if {$tcl_platform(platform)!="windows"} {
# short field (one that fits into a Mem buffer without mallocing # short field (one that fits into a Mem buffer without mallocing
# for space). # for space).
# #
do_ioerr_test ioerr-8 -tclprep { do_ioerr_test ioerr-8 -ckrefcount true -tclprep {
execsql { execsql {
CREATE TABLE t1(a,b,c); CREATE TABLE t1(a,b,c);
INSERT INTO t1 VALUES(randstr(200,200), randstr(1000,1000), 2); INSERT INTO t1 VALUES(randstr(200,200), randstr(1000,1000), 2);
@@ -207,7 +206,7 @@ do_ioerr_test ioerr-8 -tclprep {
# For test coverage: Cause an IO error whilst reading the master-journal # For test coverage: Cause an IO error whilst reading the master-journal
# name from a journal file. # name from a journal file.
if {$tcl_platform(platform)=="unix"} { if {$tcl_platform(platform)=="unix"} {
do_ioerr_test ioerr-9 -tclprep { do_ioerr_test ioerr-9 -ckrefcount true -tclprep {
execsql { execsql {
CREATE TABLE t1(a,b,c); CREATE TABLE t1(a,b,c);
INSERT INTO t1 VALUES(randstr(200,200), randstr(1000,1000), 2); INSERT INTO t1 VALUES(randstr(200,200), randstr(1000,1000), 2);
@@ -232,7 +231,7 @@ if {$tcl_platform(platform)=="unix"} {
# For test coverage: Cause an IO error during statement playback (i.e. # For test coverage: Cause an IO error during statement playback (i.e.
# a constraint). # a constraint).
do_ioerr_test ioerr-10 -tclprep { do_ioerr_test ioerr-10 -ckrefcount true -tclprep {
execsql { execsql {
BEGIN; BEGIN;
CREATE TABLE t1(a PRIMARY KEY, b); CREATE TABLE t1(a PRIMARY KEY, b);
@@ -260,7 +259,7 @@ do_ioerr_test ioerr-10 -tclprep {
# Assertion fault bug reported by alex dimitrov. # Assertion fault bug reported by alex dimitrov.
# #
do_ioerr_test ioerr-11 -erc 1 -sqlprep { do_ioerr_test ioerr-11 -ckrefcount true -erc 1 -sqlprep {
CREATE TABLE A(Id INTEGER, Name TEXT); CREATE TABLE A(Id INTEGER, Name TEXT);
INSERT INTO A(Id, Name) VALUES(1, 'Name'); INSERT INTO A(Id, Name) VALUES(1, 'Name');
} -sqlbody { } -sqlbody {
@@ -272,7 +271,7 @@ do_ioerr_test ioerr-11 -erc 1 -sqlprep {
# memory-management is enabled. # memory-management is enabled.
# #
ifcapable memorymanage { ifcapable memorymanage {
do_ioerr_test memmanage-ioerr1 -sqlprep { do_ioerr_test memmanage-ioerr1 -ckrefcount true -sqlprep {
BEGIN; BEGIN;
CREATE TABLE t1(a, b, c); CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(randstr(50,50), randstr(100,100), randstr(10,10)); INSERT INTO t1 VALUES(randstr(50,50), randstr(100,100), randstr(10,10));

View File

@@ -11,7 +11,7 @@
# This file implements some common TCL routines used for regression # This file implements some common TCL routines used for regression
# testing the SQLite library # testing the SQLite library
# #
# $Id: tester.tcl,v 1.116 2008/04/17 19:14:02 drh Exp $ # $Id: tester.tcl,v 1.117 2008/05/05 15:26:51 danielk1977 Exp $
# #
# What for user input before continuing. This gives an opportunity # What for user input before continuing. This gives an opportunity
@@ -575,6 +575,7 @@ proc do_ioerr_test {testname args} {
set ::ioerropts(-erc) 0 set ::ioerropts(-erc) 0
set ::ioerropts(-count) 100000000 set ::ioerropts(-count) 100000000
set ::ioerropts(-persist) 1 set ::ioerropts(-persist) 1
set ::ioerropts(-ckrefcount) 0
array set ::ioerropts $args array set ::ioerropts $args
set ::go 1 set ::go 1
@@ -683,10 +684,23 @@ proc do_ioerr_test {testname args} {
expr { ($s && !$r && !$q) || (!$s && $r && $q) } expr { ($s && !$r && !$q) || (!$s && $r && $q) }
} {1} } {1}
if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-ckrefcount)} {
# Check that no page references were leaked. There should be
# a single reference if there is still an active transaction,
# or zero otherwise.
do_test $testname.$n.4 {
set bt [btree_from_db db]
db_enter db
array set stats [btree_pager_stats $bt]
db_leave db
set stats(ref)
} [expr {[sqlite3_get_autocommit db]?0:1}]
}
# If an IO error occured, then the checksum of the database should # If an IO error occured, then the checksum of the database should
# be the same as before the script that caused the IO error was run. # be the same as before the script that caused the IO error was run.
if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-cksum)} { if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-cksum)} {
do_test $testname.$n.4 { do_test $testname.$n.5 {
catch {db close} catch {db close}
set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db] set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db]
cksum cksum