diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pager.c | 6 | ||||
-rw-r--r-- | src/pager.h | 4 | ||||
-rw-r--r-- | src/sqlite.h.in | 1 | ||||
-rw-r--r-- | src/util.c | 17 | ||||
-rw-r--r-- | src/wal.c | 49 | ||||
-rw-r--r-- | src/wal.h | 4 |
6 files changed, 69 insertions, 12 deletions
diff --git a/src/pager.c b/src/pager.c index 12a78cde8..31bcb32a0 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7706,4 +7706,10 @@ int sqlite3PagerWalFramesize(Pager *pPager){ } #endif +#ifdef SQLITE_USE_SEH +int sqlite3PagerWalSystemErrno(Pager *pPager){ + return sqlite3WalSystemErrno(pPager->pWal); +} +#endif + #endif /* SQLITE_OMIT_DISKIO */ diff --git a/src/pager.h b/src/pager.h index 8d899bd1a..dde845a02 100644 --- a/src/pager.h +++ b/src/pager.h @@ -239,4 +239,8 @@ void sqlite3PagerRekey(DbPage*, Pgno, u16); # define enable_simulated_io_errors() #endif +#ifdef SQLITE_USE_SEH +int sqlite3PagerWalSystemErrno(Pager*); +#endif + #endif /* SQLITE_PAGER_H */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index e4ea66a72..6a2cc53c6 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -528,6 +528,7 @@ int sqlite3_exec( #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) +#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) diff --git a/src/util.c b/src/util.c index 2d1c64ad1..3eb0419b6 100644 --- a/src/util.c +++ b/src/util.c @@ -136,6 +136,23 @@ void sqlite3ErrorClear(sqlite3 *db){ */ void sqlite3SystemError(sqlite3 *db, int rc){ if( rc==SQLITE_IOERR_NOMEM ) return; +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_IOERR_IN_PAGE ){ + int ii; + int iErr; + sqlite3BtreeEnterAll(db); + for(ii=0; ii<db->nDb; ii++){ + if( db->aDb[ii].pBt ){ + iErr = sqlite3PagerWalSystemErrno(sqlite3BtreePager(db->aDb[ii].pBt)); + if( iErr ){ + db->iSysErrno = iErr; + } + } + } + sqlite3BtreeLeaveAll(db); + return; + } +#endif rc &= 0xff; if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ db->iSysErrno = sqlite3OsGetLastError(db->pVfs); @@ -534,6 +534,7 @@ struct Wal { #ifdef SQLITE_USE_SEH u32 lockMask; /* Mask of locks held */ void *pFree; /* Pointer to sqlite3_free() if exception thrown */ + int iSysErrno; /* System error code following exception */ #endif #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ @@ -628,7 +629,7 @@ struct WalIterator { # define SEH_EXCEPT(X) \ VVA_ONLY(pWal->nSehTry--); \ assert( pWal->nSehTry==0 ); \ - } __except( sehExceptionFilter(pWal, GetExceptionCode()) ){ X } + } __except( sehExceptionFilter(pWal, GetExceptionCode(), GetExceptionInformation() ) ){ X } # define SEH_INJECT_FAULT sehInjectFault(pWal) @@ -638,9 +639,12 @@ struct WalIterator { ** indicates that the exception may have been caused by accessing the *-shm ** file mapping. Or EXCEPTION_CONTINUE_SEARCH otherwise. */ -static int sehExceptionFilter(Wal *pWal, int eCode){ +static int sehExceptionFilter(Wal *pWal, int eCode, EXCEPTION_POINTERS *p){ VVA_ONLY(pWal->nSehTry--); if( eCode==EXCEPTION_IN_PAGE_ERROR ){ + if( p && p->ExceptionRecord && p->ExceptionRecord->NumberParameters>=3 ){ + pWal->iSysErrno = (int)p->ExceptionRecord->ExceptionInformation[2]; + } return EXCEPTION_EXECUTE_HANDLER; } return EXCEPTION_CONTINUE_SEARCH; @@ -653,10 +657,17 @@ static int sehExceptionFilter(Wal *pWal, int eCode){ ** has been invalidated. */ static void sehInjectFault(Wal *pWal){ - assert( pWal->nSehTry>0 ); - if( sqlite3FaultSim(650) ){ - RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 0, NULL); - } + int res; + assert( pWal->nSehTry>0 ); + + res = sqlite3FaultSim(650); + if( res!=0 ){ + ULONG aArg[3]; + aArg[0] = 0; + aArg[1] = 0; + aArg[2] = (ULONG)res; + RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 3, aArg); + } } /* @@ -2353,7 +2364,7 @@ static int walHandleException(Wal *pWal){ } sqlite3_free(pWal->pFree); pWal->pFree = 0; - return SQLITE_IOERR; + return SQLITE_IOERR_IN_PAGE; } /* @@ -2379,6 +2390,20 @@ static int walAssertLockmask(Wal *pWal){ } return 1; } + +/* +** Return and zero the "system error" field set when an +** EXCEPTION_IN_PAGE_ERROR exception is caught. +*/ +int sqlite3WalSystemErrno(Wal *pWal){ + int iRet = 0; + if( pWal ){ + iRet = pWal->iSysErrno; + pWal->iSysErrno = 0; + } + return iRet; +} + #else # define walAssertLockmask(x) 1 #endif /* ifdef SQLITE_USE_SEH */ @@ -3151,7 +3176,7 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ SEH_TRY { rc = walSnapshotRecover(pWal, pBuf1, pBuf2); } - SEH_EXCEPT( rc = SQLITE_IOERR; ) + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) pWal->ckptLock = 0; } @@ -3436,7 +3461,7 @@ int sqlite3WalFindFrame( SEH_TRY { rc = walFindFrame(pWal, pgno, piRead); } - SEH_EXCEPT( rc = SQLITE_IOERR; ) + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) return rc; } @@ -3526,7 +3551,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ rc = SQLITE_BUSY_SNAPSHOT; } } - SEH_EXCEPT( rc = SQLITE_IOERR; ) + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) if( rc!=SQLITE_OK ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); @@ -3593,7 +3618,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ } if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); } - SEH_EXCEPT( rc = SQLITE_IOERR; ) + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) } return rc; } @@ -3640,7 +3665,7 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ SEH_TRY { walCleanupHash(pWal); } - SEH_EXCEPT( rc = SQLITE_IOERR; ) + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) } return rc; @@ -151,5 +151,9 @@ int sqlite3WalWriteLock(Wal *pWal, int bLock); void sqlite3WalDb(Wal *pWal, sqlite3 *db); #endif +#ifdef SQLITE_USE_SEH +int sqlite3WalSystemErrno(Wal*); +#endif + #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ |