diff --git a/main.mk b/main.mk index 60df83514d..06d4eff815 100644 --- a/main.mk +++ b/main.mk @@ -118,7 +118,6 @@ TESTSRC = \ $(TOP)/src/os_mac.c \ $(TOP)/src/os_unix.c \ $(TOP)/src/os_win.c \ - $(TOP)/src/os_test.c \ $(TOP)/src/pager.c \ $(TOP)/src/pragma.c \ $(TOP)/src/printf.c \ @@ -274,9 +273,6 @@ opcodes.h: $(TOP)/src/vdbe.h os_mac.o: $(TOP)/src/os_mac.c $(HDR) $(TCCX) -c $(TOP)/src/os_mac.c -os_test.o: $(TOP)/src/os_test.c $(HDR) - $(TCCX) -c $(TOP)/src/os_test.c - os_unix.o: $(TOP)/src/os_unix.c $(HDR) $(TCCX) -c $(TOP)/src/os_unix.c @@ -359,9 +355,9 @@ testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) -testfixturex: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) - $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o testfixturex \ - $(TESTSRC) $(TOP)/src/tclsqlite.c \ +crashtest: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TOP)/src/os_test.c + $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o crashtest \ + $(TESTSRC) $(TOP)/src/os_test.c $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) fulltest: testfixture$(EXE) sqlite3$(EXE) diff --git a/manifest b/manifest index 52e8c13c5a..2f812b2429 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scomment\sto\sthe\soutput\sbuffer\sallocation\sin\ssqlite3VdbeMemTranslate()\s(CVS\s1673) -D 2004-06-23T00:23:49 +C Handle\scorrupt\sjournal\sfile\sheaders\scorrectly.\s(CVS\s1674) +D 2004-06-23T01:05:27 F Makefile.in 0a3d7aaefa50717bd550b0cf568a51072c4c103c F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -17,7 +17,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826 -F main.mk 5dbdfd52ee306c553c88278d7dc4adb58a662209 +F main.mk a14f6389bce136c336206ec58b69305ab12ba5fa F mkdll.sh 68d34a961a1fdfa15ef27fc4f4740be583112124 F publish.sh 4193d9022fb7cf9beecd313bed3d1d68b8386fbe F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b @@ -50,7 +50,7 @@ F src/os_unix.c 39e73ed02fc992a6bfc52200ea26704633412cc0 F src/os_unix.h 00c1f82b526ab2fb7ee5ddd555ea4ed68363c93a F src/os_win.c 84549f6cc815237533c5d0eb3697352b03478d96 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44 -F src/pager.c 5fac95a8fef916a4c5915ccc3b8dc72312681880 +F src/pager.c 42297421e9e7646f99b332c69f3f8085c1d765bf F src/pager.h bc58d32a9dee464f7268fb68652c130a4216e438 F src/parse.y 097438674976355a10cf177bd97326c548820b86 F src/pragma.c 0750e1c360647dbe0a991f16133b0fe5e42e5039 @@ -104,7 +104,7 @@ F test/collate4.test 0e9fc08ffcf6eddf72e354a15de06688fa86db31 F test/collate5.test 1dd5f0f508c46667f9d4606c7950c414b0bdc0d5 F test/collate6.test 2a45768914f04c1447a69d1358bbede376552675 F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87 -F test/crash.test b6ff4701ca4c30553dc819eab9d8b1226ca39af2 +F test/crash.test fa7c6ef4d1ac1aa2d14d8afd1583cef8f8e2a0e4 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d F test/delete.test 4f0c86e2bebdc822d179c80697b1ceabe6bbcd07 @@ -113,7 +113,7 @@ F test/enc2.test 57c847492afd46eef7a498fc3853fe909a40fef7 F test/enc3.test 315f302ed9a6042be76710eb6aa70e4551e9aa73 F test/expr.test b4e945265c4c697bf5213b72558914ba10a989cc F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7 -F test/func.test c97954ad23bdbc58e2b73f264f6a006bae79f626 +F test/func.test 95eba35f06e56e66fa40726957ce103b4e6ffe73 F test/hook.test c4102c672d67f8fb60ea459842805abcba69a747 F test/in.test b92a2df9162e1cbd33c6449a29a05e6955b1741a F test/index.test b6941dd532815f278042b85f79b1a6dc16c4d729 @@ -229,7 +229,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P cb4e242e83ba111c5da1f9662fda5a890051e7b0 -R bd4ff00f259823f00b7fc8204e6c5fa3 +P e2f7f182987fbfe8611ead8bd1f12b2e8b47f6dc +R 8314e42b760c1a8a452b6f1accd15858 U danielk1977 -Z ed06ef82d5f64ca5dbd5ac31ceda856c +Z 0fc9a3cf7f51cb64d701f7be6ce96ff8 diff --git a/manifest.uuid b/manifest.uuid index e7598a1756..6307d2cddf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2f7f182987fbfe8611ead8bd1f12b2e8b47f6dc \ No newline at end of file +46107da7eddbdda8b582e2ece2dc41222a70330a \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 4f73e7629b..9e46ef899c 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.135 2004/06/22 12:18:32 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.136 2004/06/23 01:05:27 danielk1977 Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" @@ -792,10 +792,13 @@ static int pager_reload_cache(Pager *pPager){ ** deleted when the power is restored) we don't care. ** ** If the file opened as the journal file is not a well-formed -** journal file then the database will likely already be -** corrupted, so the PAGER_ERR_CORRUPT bit is set in pPager->errMask -** and SQLITE_CORRUPT is returned. If it all works, then this routine -** returns SQLITE_OK. +** journal file then all pages up to the first corrupted page are rolled +** back (or no pages if the journal header is corrupted). The journal file +** is then deleted and SQLITE_OK returned, just as if no corruption had +** been encountered. +** +** If an I/O or malloc() error occurs, the journal-file is not deleted +** and an error code is returned. */ static int pager_playback(Pager *pPager, int useJournalSize){ off_t szJ; /* Size of the journal file in bytes */ @@ -831,7 +834,6 @@ static int pager_playback(Pager *pPager, int useJournalSize){ ** at the beginning of the journal. */ rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic)); if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ - rc = SQLITE_PROTOCOL; goto end_playback; } @@ -857,6 +859,7 @@ static int pager_playback(Pager *pPager, int useJournalSize){ ** specified, only proceed with the playback if it still exists. */ rc = read32bits(&pPager->jfd, &nMaster); if( rc ) goto end_playback; + if( szJ < 24+nMaster ) goto end_playback; if( nMaster>0 ){ zMaster = sqliteMalloc(nMaster); if( !zMaster ){ @@ -908,15 +911,7 @@ end_playback: } sqliteFree(zMaster); } - if( rc!=SQLITE_OK ){ - /* FIX ME: We shouldn't delete the journal if an error occured during - ** rollback. It may have been a transient error and the rollback may - ** succeed next time it is attempted. - */ - pager_unwritelock(pPager); - pPager->errMask |= PAGER_ERR_CORRUPT; - rc = SQLITE_CORRUPT; - }else{ + if( rc==SQLITE_OK ){ rc = pager_unwritelock(pPager); } return rc; diff --git a/test/crash.test b/test/crash.test index 8e03764721..e287c33051 100644 --- a/test/crash.test +++ b/test/crash.test @@ -10,19 +10,40 @@ #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: crash.test,v 1.1 2004/06/22 13:12:52 danielk1977 Exp $ +# $Id: crash.test,v 1.2 2004/06/23 01:05:27 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl -proc run_testfixturex {script} { +# This proc execs a seperate process that crashes midway through executing +# the SQL script $sql on database test.db. +# +# Argument $crashdelay indicates the number of file closes or syncs to wait +# before crashing. When a crash occurs a random subset of unsynced writes +# are written into any open files. +proc crashsql {crashdelay sql} { + set f [open crash.tcl w] - puts $f $script + puts $f "sqlite3_crashseed $crashdelay" + puts $f "sqlite3 db test.db" + puts $f "db eval {" + puts $f "$sql" + puts $f "}" close $f - exec ./testfixturex crash.tcl + exec [file join . crashtest] crash.tcl } +# Simple crash test: +# +# crash-1.1: Create a database with a table with two rows. +# crash-1.2: Run a 'DELETE FROM abc WHERE a = 1' that crashes during +# journal-sync +# crash-1.3: Ensure the database is in the same state as after crash-1.1. +# crash-1.4: Run a 'DELETE FROM abc WHERE a = 1' that crashes during +# database-sync +# crash-1.5: Ensure the database is in the same state as after crash-1.1. +# do_test crash-1.1 { execsql { CREATE TABLE abc(a, b, c); @@ -30,43 +51,32 @@ do_test crash-1.1 { INSERT INTO abc VALUES(4, 5, 6); } } {} - do_test crash-1.2 { - set script { - sqlite3_crashseed 1 - sqlite3 db test.db - db eval {pragma synchronous=full;} - db eval {DELETE FROM abc WHERE a = 1;} - } catch { - run_testfixturex $script + crashsql 1 { + DELETE FROM abc WHERE a = 1; + } } msg set msg } {child process exited abnormally} - do_test crash-1.3 { catchsql { SELECT * FROM abc; } } {0 {1 2 3 4 5 6}} - do_test crash-1.4 { - set script { - sqlite3_crashseed 2 - sqlite3 db test.db - db eval {DELETE FROM abc WHERE a = 1;} - } catch { - run_testfixturex $script + crashsql 1 { + DELETE FROM abc WHERE a = 1; + } } msg set msg } {child process exited abnormally} - do_test crash-1.5 { - catch { + catchsql { SELECT * FROM abc; } -} {1 2 3 4 5 6} +} {0 {1 2 3 4 5 6}} finish_test diff --git a/test/func.test b/test/func.test index de8ab615ff..590aaa8cc4 100644 --- a/test/func.test +++ b/test/func.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing built-in functions. # -# $Id: func.test,v 1.24 2004/06/19 17:33:08 drh Exp $ +# $Id: func.test,v 1.25 2004/06/23 01:05:27 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -392,6 +392,7 @@ do_test func-13.1 { SELECT test_auxdata('hello world'); } } {0} + do_test func-13.2 { execsql { CREATE TABLE t4(a, b); @@ -434,5 +435,4 @@ do_test func-13.7 { lappend res [sqlite3_finalize $STMT] } {{0 0} {1 0} SQLITE_OK} - finish_test