aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pager.c6
-rw-r--r--src/pager.h4
-rw-r--r--src/sqlite.h.in1
-rw-r--r--src/util.c17
-rw-r--r--src/wal.c49
-rw-r--r--src/wal.h4
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);
diff --git a/src/wal.c b/src/wal.c
index f832e1b01..78ef82145 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -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;
diff --git a/src/wal.h b/src/wal.h
index 02e2bab36..d39bb50f3 100644
--- a/src/wal.h
+++ b/src/wal.h
@@ -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 */