Improve coverage of pager.c. (CVS 6158)

FossilOrigin-Name: 855c4093cf331496d9ef508011ad814e91e3882f
This commit is contained in:
danielk1977 2009-01-10 16:15:09 +00:00
parent 96c7a7d95f
commit 7cbd589da0
7 changed files with 163 additions and 61 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\sbug\scaused\sby\soverzealous\scode\stest\scoverage\ssimplifications.\nBug\sfound\sby\sTH3.\s(CVS\s6157)
D 2009-01-10T15:34:12
C Improve\scoverage\sof\spager.c.\s(CVS\s6158)
D 2009-01-10T16:15:09
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 05461a9b5803d5ad10c79f989801e9fd2cc3e592
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
F src/os_unix.c 7825c6178597713382d74adbf8c8c00ffcdc42d4
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
F src/pager.c 97bfbacae6131b8d228628803606e98dd763b474
F src/pager.c a1e23f2c55bda1303cb6236d4aca9666e58eb610
F src/pager.h 9870acb2d653848d90d765d7cbf163496d6c8111
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
@ -159,7 +159,7 @@ F src/shell.c 65d19f8996a160f288087e31810f24025439c62a
F src/sqlite.h.in 6cd2489e40fe97ba58c60044a4ced377e08b6d09
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 4b2a8eb466c30daa90d25f9d3bb2e85b60ad47af
F src/sqliteLimit.h 651a2757ba55aeba1da167786b6a8c3404433940
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 23db1e5f27c03160987c122a078b4bb51ef0b2f8
F src/tclsqlite.c 4415e1033bd3e92b05a6a9cde911ee4de3b82df9
@ -288,7 +288,7 @@ F test/crash4.test 02ff4f15c149ca1e88a5c299b4896c84d9450c3b
F test/crash5.test 80a2f7073381837fc082435c97df52a830abcd80
F test/crash6.test 9c730cf06335003cb1f5cfceddacd044155336e0
F test/crash7.test e20a7b9ee1d16eaef7c94a4cb7ed2191b4d05970
F test/crash8.test 2ee8ecfed37eea4b987148fe36d6b56175c7d049
F test/crash8.test 5b0e499c1dfaa2025e8ab69e4be32f71d4d92b23
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
@ -413,7 +413,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
F test/jrnlmode.test e004a5ed138e06464d74dbd6bead01908f264c52
F test/jrnlmode.test a77f95a7cbdc8373582fd274f24124ad0d3a8fb6
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 22f7857f9d7da7ff5061ded8806c43a6271109fc
@ -430,7 +430,7 @@ F test/lock6.test f4e9052b14da3bd6807a757d5aed15c17321031a
F test/lookaside.test e69f822f13745f1d5c445c6e30e30f059f30c8e5
F test/main.test 187a9a1b5248ed74a83838c581c15ec6023b555b
F test/make-where7.tcl 40bb740b37eead343eaf57b74ab72d2a5a304745
F test/malloc.test 86f378c52202b5b39b54a7fc560a4a75d77ce4f1
F test/malloc.test 95e94f8a3dd1169c8774788ec4148ea032ea20d8
F test/malloc3.test 4bc57f850b212f706f3e1b37c4eced1d5a727cd1
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test 20d1a0884b03edf811bfd7005faade028367e7c8
@ -696,7 +696,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 2cbea64fb00a1b5b8aa0e9c958b2a09256ae59bc
R 7759d6bbe5785c316ce1fcb98ad155c6
U drh
Z 8f01cd8c083356c8b7a4a4354e84f698
P 3da5578726cb22118dfca38a2098a1e378644387
R 320ab8e7bd88e5e4d3a0d64f8789cffb
U danielk1977
Z 43f0761b39243fe434b2dca241a4ad9a

View File

@ -1 +1 @@
3da5578726cb22118dfca38a2098a1e378644387
855c4093cf331496d9ef508011ad814e91e3882f

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.544 2009/01/09 17:11:05 danielk1977 Exp $
** @(#) $Id: pager.c,v 1.545 2009/01/10 16:15:09 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@ -116,6 +116,14 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
# define CODEC2(P,D,N,X) ((char*)D)
#endif
/*
** The maximum allowed sector size. 16MB. If the xSectorsize() method
** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
** This could conceivably cause corruption following a power failure on
** such a system. This is currently an undocumented limit.
*/
#define MAX_SECTOR_SIZE 0x0100000
/*
** An instance of the following structure is allocated for each active
** savepoint and statement transaction in the system. All such structures
@ -401,7 +409,7 @@ static int jrnlBufferSize(Pager *pPager){
if( fd->pMethods ){
dc = sqlite3OsDeviceCharacteristics(fd);
nSector = sqlite3OsSectorSize(fd);
nSector = pPager->sectorSize;
szPage = pPager->pageSize;
}
@ -760,7 +768,8 @@ static int readJournalHdr(
int rc;
unsigned char aMagic[8]; /* A buffer to hold the magic header */
i64 jrnlOff;
int iPageSize;
u32 iPageSize;
u32 iSectorSize;
seekJournalHdr(pPager);
if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
@ -785,28 +794,41 @@ static int readJournalHdr(
rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
if( rc ) return rc;
rc = read32bits(pPager->jfd, jrnlOff+16, (u32 *)&iPageSize);
if( rc==SQLITE_OK
&& iPageSize>=512
&& iPageSize<=SQLITE_MAX_PAGE_SIZE
&& ((iPageSize-1)&iPageSize)==0
){
u16 pagesize = (u16)iPageSize;
rc = sqlite3PagerSetPagesize(pPager, &pagesize);
}
if( rc ) return rc;
if( pPager->journalOff==0 ){
rc = read32bits(pPager->jfd, jrnlOff+16, &iPageSize);
if( rc ) return rc;
/* Update the assumed sector-size to match the value used by
** the process that created this journal. If this journal was
** created by a process other than this one, then this routine
** is being called from within pager_playback(). The local value
** of Pager.sectorSize is restored at the end of that routine.
*/
rc = read32bits(pPager->jfd, jrnlOff+12, &pPager->sectorSize);
if( rc ) return rc;
if( (pPager->sectorSize & (pPager->sectorSize-1))!=0
|| pPager->sectorSize>0x1000000 ){
return SQLITE_DONE;
if( iPageSize<512
|| iPageSize>SQLITE_MAX_PAGE_SIZE
|| ((iPageSize-1)&iPageSize)!=0
){
/* If the page-size in the journal-header is invalid, then the process
** that wrote the journal-header must have crashed before the header
** was synced. In this case stop reading the journal file here.
*/
rc = SQLITE_DONE;
}else{
u16 pagesize = (u16)iPageSize;
rc = sqlite3PagerSetPagesize(pPager, &pagesize);
assert( rc!=SQLITE_OK || pagesize==(u16)iPageSize );
}
if( rc ) return rc;
/* Update the assumed sector-size to match the value used by
** the process that created this journal. If this journal was
** created by a process other than this one, then this routine
** is being called from within pager_playback(). The local value
** of Pager.sectorSize is restored at the end of that routine.
*/
rc = read32bits(pPager->jfd, jrnlOff+12, &iSectorSize);
if( rc ) return rc;
if( (iSectorSize&(iSectorSize-1))
|| iSectorSize<512
|| iSectorSize>MAX_SECTOR_SIZE
){
return SQLITE_DONE;
}
pPager->sectorSize = iSectorSize;
}
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
@ -1503,7 +1525,7 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
** Set the sectorSize for the given pager.
**
** The sector size is at least as big as the sector size reported
** by sqlite3OsSectorSize(). The minimum sector size is 512.
** by sqlite3OsSectorSize(). The minimum sector size is 512.
*/
static void setSectorSize(Pager *pPager){
assert(pPager->fd->pMethods||pPager->tempFile);
@ -1517,6 +1539,9 @@ static void setSectorSize(Pager *pPager){
if( pPager->sectorSize<512 ){
pPager->sectorSize = 512;
}
if( pPager->sectorSize>MAX_SECTOR_SIZE ){
pPager->sectorSize = MAX_SECTOR_SIZE;
}
}
/*
@ -2022,9 +2047,9 @@ int sqlite3PagerOpen(
** + The largest page size that can be written atomically.
*/
if( rc==SQLITE_OK && !readOnly ){
int iSectorSize = sqlite3OsSectorSize(pPager->fd);
if( szPageDflt<iSectorSize ){
szPageDflt = iSectorSize;
setSectorSize(pPager);
if( szPageDflt<pPager->sectorSize ){
szPageDflt = pPager->sectorSize;
}
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
{

View File

@ -12,7 +12,7 @@
**
** This file defines various limits of what SQLite can process.
**
** @(#) $Id: sqliteLimit.h,v 1.9 2009/01/07 16:15:43 danielk1977 Exp $
** @(#) $Id: sqliteLimit.h,v 1.10 2009/01/10 16:15:09 danielk1977 Exp $
*/
/*
@ -130,6 +130,13 @@
/* Maximum page size. The upper bound on this value is 32768. This a limit
** imposed by the necessity of storing the value in a 2-byte unsigned integer
** and the fact that the page size must be a power of 2.
**
** If this limit is changed, then the compiled library is technically
** incompatible with an SQLite library compiled with a different limit. If
** a process operating on a database with a page-size of 65536 bytes
** crashes, then an instance of SQLite compiled with the default page-size
** limit will not be able to rollback the aborted transaction. This could
** lead to database corruption.
*/
#ifndef SQLITE_MAX_PAGE_SIZE
# define SQLITE_MAX_PAGE_SIZE 32768

View File

@ -15,7 +15,7 @@
# Later: Also, some other specific scenarios required for coverage
# testing that do not lead to corruption.
#
# $Id: crash8.test,v 1.2 2009/01/09 10:49:14 danielk1977 Exp $
# $Id: crash8.test,v 1.3 2009/01/10 16:15:09 danielk1977 Exp $
set testdir [file dirname $argv0]
@ -118,13 +118,27 @@ proc read_file {zFile} {
close $fd
return $zData
}
proc write_file {zFile zData} {
set fd [open $zFile w]
fconfigure $fd -translation binary
puts -nonewline $fd $zData
close $fd
}
# The following tests check that SQLite will not roll back a hot-journal
# file if the sector-size field in the first journal file header is
# suspect. Definition of suspect:
#
# a) Not a power of 2, or (crash8-3.5)
# b) Greater than 0x01000000 (16MB), or (crash8-3.6)
# c) Less than 512. (crash8-3.7)
#
# Also test that SQLite will not rollback a hot-journal file with a
# suspect page-size. In this case "suspect" means:
#
# a) Not a power of 2, or
# b) Greater than 0x1000000 (16MB).
# b) Less than 512, or
# c) Greater than SQLITE_MAX_PAGE_SIZE
#
do_test crash8-3.1 {
list [file exists test.db-joural] [file exists test.db]
@ -148,34 +162,61 @@ do_test crash8-3.4 {
binary scan [string range $zJournal 20 23] I nSector
set nSector
} {512}
do_test crash8-3.5 {
set zJournal2 [
string replace $zJournal 20 23 [binary format I 511]
]
set fd [open test.db-journal w]
fconfigure $fd -translation binary
puts -nonewline $fd $zJournal2
close $fd
set zJournal2 [string replace $zJournal 20 23 [binary format I 513]]
write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.6 {
set zJournal2 [
string replace $zJournal 20 23 [binary format I [expr 0x2000000]]
]
set fd [open test.db-journal w]
fconfigure $fd -translation binary
puts -nonewline $fd $zJournal2
close $fd
set zJournal2 [string replace $zJournal 20 23 [binary format I 0x2000000]]
write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.7 {
set zJournal2 [string replace $zJournal 20 23 [binary format I 256]]
write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.8 {
set zJournal2 [string replace $zJournal 24 27 [binary format I 513]]
write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.9 {
set big [expr $SQLITE_MAX_PAGE_SIZE * 2]
set zJournal2 [string replace $zJournal 24 27 [binary format I $big]]
write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.10 {
set zJournal2 [string replace $zJournal 24 27 [binary format I 256]]
write_file test.db-journal $zJournal2
execsql {
SELECT count(*) FROM t1;
PRAGMA integrity_check
}
} {0 ok}
do_test crash8-3.11 {
set fd [open test.db-journal w]
fconfigure $fd -translation binary
puts -nonewline $fd $zJournal

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The focus
# of these tests is the journal mode pragma.
#
# $Id: jrnlmode.test,v 1.10 2009/01/09 10:49:14 danielk1977 Exp $
# $Id: jrnlmode.test,v 1.11 2009/01/10 16:15:09 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -419,6 +419,23 @@ ifcapable pragma {
set sz [file size test.db-journal]
expr {$sz>=$journalsize}
} {1}
# Test a size-limit of 0.
#
do_test jrnlmode-5.20 {
execsql {
PRAGMA journal_size_limit = 0;
BEGIN;
UPDATE t1 SET a = randomblob(1000);
}
} {0}
do_test jrnlmode-5.21 {
expr {[file size test.db-journal] > 1024}
} {1}
do_test jrnlmode-5.22 {
execsql COMMIT
list [file exists test.db-journal] [file size test.db-journal]
} {1 0}
}
ifcapable pragma {

View File

@ -16,7 +16,7 @@
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.72 2009/01/10 11:13:40 danielk1977 Exp $
# $Id: malloc.test,v 1.73 2009/01/10 16:15:09 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -678,7 +678,7 @@ do_malloc_test 29 -sqlprep {
INSERT INTO t1 SELECT * FROM t1 UNION ALL SELECT * FROM t1;
}
do_malloc_test 29 -tclprep {
do_malloc_test 30 -tclprep {
db eval {
CREATE TABLE t1(x PRIMARY KEY);
INSERT INTO t1 VALUES(randstr(500,500));
@ -708,6 +708,18 @@ do_malloc_test 29 -tclprep {
SELECT * FROM t1 ORDER BY x;
}
# After committing a transaction in persistent-journal mode, if a journal
# size limit is configured SQLite may attempt to truncate the journal file.
# This test verifies the libraries response to a malloc() failure during
# this operation.
#
do_malloc_test 31 -sqlprep {
PRAGMA journal_mode = persist;
PRAGMA journal_size_limit = 1024;
CREATE TABLE t1(a PRIMARY KEY, b);
} -sqlbody {
INSERT INTO t1 VALUES(1, 2);
}
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {