diff --git a/manifest b/manifest index d417bb139e..18648cc431 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\sassert()\sstatements\sand\sfix\ssmall\sissues\swith\scode\son\sthis\sbranch. -D 2021-08-20T16:19:19.544 +C Add\smissing\sSEH_INJECT_FAULT\smacros. +D 2021-08-20T17:23:19.198 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb7 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vtab.c 88404ac1517903b3eb2abe256772ee95bb09f81ac0a17e13afe5d467df4de4ee F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c d47742fa0d58fa622416cfd105b4b309f39006f30d903e02db2f48236f3d83d7 +F src/wal.c 5f98987c924f3262e19bc1c124cc4e02553f768a86cfdfb4d193db04c4d0b3da F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac F src/where.c 99b6e13664a7bd9a553c554978d0e253066995dade621f44cffa8928c8b493b5 @@ -1921,7 +1921,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a98820c3d20766813bb4b0da23247ac90f380c07827ff13b61d5b606d8311aa -R eab33be79c818813f4366ae19768ee1d +P bd9b373b177a71f5eaeb7ce8dd1dc755b34951ee1376c24652418bb329bfcb45 +R 18bce27bc9709a49e95cb84782c68c82 U dan -Z 8887602c0a0185b63b60ad6538fd96e1 +Z 8c053f205f09cec18507fce552900c67 diff --git a/manifest.uuid b/manifest.uuid index 4034ae736f..f413569b7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd9b373b177a71f5eaeb7ce8dd1dc755b34951ee1376c24652418bb329bfcb45 \ No newline at end of file +27e9bdb3a90a5826f45d32e0378e9afa90a16ac762a75236f38218f41bc45ded \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index f6c2d86df8..ef50aac040 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1133,6 +1133,7 @@ static int walFramePage(u32 iFrame){ */ static u32 walFramePgno(Wal *pWal, u32 iFrame){ int iHash = walFramePage(iFrame); + SEH_INJECT_FAULT; if( iHash==0 ){ return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; } @@ -1228,7 +1229,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ idx = iFrame - sLoc.iZero; assert( idx <= HASHTABLE_NSLOT/2 + 1 ); - + /* If this is the first entry to be added to this hash-table, zero the ** entire hash table and aPgno[] array before proceeding. */ @@ -1467,6 +1468,7 @@ static int walIndexRecover(Wal *pWal){ } } #endif + SEH_INJECT_FAULT; if( iFrame<=iLast ) break; } @@ -1498,6 +1500,7 @@ finished: }else{ pInfo->aReadMark[i] = READMARK_NOT_USED; } + SEH_INJECT_FAULT; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc!=SQLITE_BUSY ){ goto recovery_error; @@ -2154,7 +2157,7 @@ static int walCheckpoint( rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); - AtomicStore(pInfo->aReadMark+i, iMark); + AtomicStore(pInfo->aReadMark+i, iMark); SEH_INJECT_FAULT; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc==SQLITE_BUSY ){ mxSafeFrame = y; @@ -2206,6 +2209,7 @@ static int walCheckpoint( while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ i64 iOffset; assert( walFramePgno(pWal, iFrame)==iDbpage ); + SEH_INJECT_FAULT; if( AtomicLoad(&db->u1.isInterrupted) ){ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; break; @@ -2235,7 +2239,7 @@ static int walCheckpoint( } } if( rc==SQLITE_OK ){ - AtomicStore(&pInfo->nBackfill, mxSafeFrame); + AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; } } @@ -2312,6 +2316,73 @@ static void walLimitSize(Wal *pWal, i64 nMax){ } } +#ifdef SQLITE_USE_SEH +/* +** This is the "standard" exception handler used in a few places to handle +** an exception thrown by reading from the *-shm mapping after it has become +** invalid in SQLITE_USE_SEH builds. It is used as follows: +** +** SEH_TRY { ... } +** SEH_EXCEPT( rc = walHandleException(pWal); ) +** +** This function does three things: +** +** 1) Determines the locks that should be held, based on the contents of +** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other +** held locks are assumed to be transient locks that would have been +** released had the exception not been thrown and are dropped. +** +** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). +** +** 3) Returns SQLITE_IOERR. +*/ +static int walHandleException(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<lockMask & ~( + (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) + ); + for(ii=0; iipFree); + pWal->pFree = 0; + return SQLITE_IOERR; +} + +/* +** Assert that the Wal.lockMask mask, which indicates the locks held +** by the connenction, is consistent with the Wal.readLock, Wal.writeLock +** and Wal.ckptLock variables. To be used as: +** +** assert( walAssertLockmask(pWal) ); +*/ +static int walAssertLockmask(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) +#ifdef SQLITE_ENABLE_SNAPSHOT + | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) +#endif + ); + assert( mExpect==pWal->lockMask ); + } + return 1; +} +#else +# define walAssertLockmask(x) 1 +#endif /* ifdef SQLITE_USE_SEH */ + /* ** Close a connection to a log file. */ @@ -2998,71 +3069,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return rc; } -#ifdef SQLITE_USE_SEH -/* -** This is the "standard" exception handler used in a few places to handle -** an exception thrown by reading from the *-shm mapping after it has become -** invalid in SQLITE_USE_SEH builds. It is used as follows: -** -** SEH_TRY { ... } -** SEH_EXCEPT( rc = walHandleException(pWal); ) -** -** This function does three things: -** -** 1) Determines the locks that should be held, based on the contents of -** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other -** held locks are assumed to be transient locks that would have been -** released had the exception not been thrown and are dropped. -** -** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). -** -** 3) Returns SQLITE_IOERR. -*/ -static int walHandleException(Wal *pWal){ - if( pWal->exclusiveMode==0 ){ - static const int S = 1; - static const int E = (1<lockMask & ~( - (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) - | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) - | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) - ); - for(ii=0; iipFree); - pWal->pFree = 0; - return SQLITE_IOERR; -} - -/* -** Assert that the Wal.lockMask mask, which indicates the locks held -** by the connenction, is consistent with the Wal.readLock, Wal.writeLock -** and Wal.ckptLock variables. To be used as: -** -** assert( walAssertLockmask(pWal) ); -*/ -static int walAssertLockmask(Wal *pWal){ - if( pWal->exclusiveMode==0 ){ - static const int S = 1; - static const int E = (1<readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) - | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) - | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) -#ifdef SQLITE_ENABLE_SNAPSHOT - | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) -#endif - ); - assert( mExpect==pWal->lockMask ); - } - return 1; -} -#endif - #ifdef SQLITE_ENABLE_SNAPSHOT /* ** This function does the work of sqlite3WalSnapshotRecover(). @@ -4167,6 +4173,7 @@ int sqlite3WalCheckpoint( /* If no error occurred, set the output variables. */ if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + SEH_INJECT_FAULT; if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); } }