]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If an EXCEPTION_IN_PAGE_ERROR exception is caught, make the underlying OS error code...
authordan <Dan Kennedy>
Fri, 10 Sep 2021 21:28:56 +0000 (21:28 +0000)
committerdan <Dan Kennedy>
Fri, 10 Sep 2021 21:28:56 +0000 (21:28 +0000)
FossilOrigin-Name: fdb20e9ee48465b94aa6ac3c5e263ecaa7c3b10f4a193e79f965b7c35944b08b

manifest
manifest.uuid
src/pager.c
src/pager.h
src/sqlite.h.in
src/util.c
src/wal.c
src/wal.h
test/walseh1.test

index 7b07305bc4ee458b7c1784debdcd94ae7aa9dfe2..a0bc1c183583112f45279a0a6914d24c81299c48 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sthe\sstructuree\sexception\shandler\sin\swal.c\sto\scatch\sEXCEPTION_IN_PAGE_ERROR\sinstead\sof\sEXCEPTION_ACCESS_VIOLATION.
-D 2021-08-26T21:12:07.088
+C If\san\sEXCEPTION_IN_PAGE_ERROR\sexception\sis\scaught,\smake\sthe\sunderlying\sOS\serror\scode\savailable\svia\ssqlite3_system_errno().
+D 2021-09-10T21:28:56.797
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -531,8 +531,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c b11e4610769922253dec27d7af4a07ff84f65169d19bda5e9b12a152a706f7f5
 F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0
-F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
+F src/pager.c 555cff0be2d255827dbc93761c0265d077faf34f31b65ccf16d76d053dfd0467
+F src/pager.h 53b3ba002dbc7568608489f67c249224102d10f372c098a1a9dd58308bc76d3c
 F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb
 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
@@ -546,7 +546,7 @@ F src/resolve.c 42b94d37a54200707a95566eff4f7e8a380e32d080016b699f23bd79a73a5028
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 0577308f097363b6ebac223e210418810acf74e677f580597f7d0718476fe3ef
 F src/shell.c.in f795a4ae3c35631f5edcfa754c7824ff1d8a75b23a07e22e664b50f82e826346
-F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145
+F src/sqlite.h.in 79d8c9a7e9886851243183e4b610022d87e6dd73bf2e1218d3105ab4577af9a0
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
 F src/sqliteInt.h a65ddfb177549c82dcd1374a2f23260328eb65ced55b50843419386177e159be
@@ -614,7 +614,7 @@ F src/trigger.c 3f612ce5f0858b6c23460a3c799d01f408b49b0b29d931d8b8e6fc224a8667de
 F src/update.c 69c4c10bc6873a80c0a77cb578f9fc60ee90003d03f9530bc3370fa24615772d
 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
-F src/util.c eafc8cfeb66fdbf8839922d13019b7882f242ac31b383e3451aab7744c54df3e
+F src/util.c a14724ed2a504488c34bd3a510ae33e46be00d0b80296651aba3a3d36303e460
 F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45
 F src/vdbe.c e5cdac52d7163c032ae3c54f1cff9391acd23ba79cea0d5a9524c00cc0a856e8
 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
@@ -628,8 +628,8 @@ F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb7
 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
 F src/vtab.c 88404ac1517903b3eb2abe256772ee95bb09f81ac0a17e13afe5d467df4de4ee
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 75bcffce59a3108ad3e24c186977821ffe5083ab2044ff477a5bbc4a9e8a5455
-F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
+F src/wal.c 8cc813d34b345728987b78bcb0a02f7b6e4734031eea1feb1b6d1d0e56ac5a21
+F src/wal.h 04a9e53121d5076f2a173b0f2facb39d33047093fee71bd3bbe6b1f6f1f5fd4b
 F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
 F src/where.c 99b6e13664a7bd9a553c554978d0e253066995dade621f44cffa8928c8b493b5
 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
@@ -1739,7 +1739,7 @@ F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db8
 F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
 F test/walro2.test 0e79dd15cbdb4f482c01ea248373669c732414a726b357d04846a816afafb768
 F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
-F test/walseh1.test 7aff09e275a10a4b140f0a34c9da55de2d3747582590f16b638831e1dd7396b2
+F test/walseh1.test 5a94409fb1a7029070040286336fef5ce61315121123e25cfb7e0622b017e59d
 F test/walsetlk.test 3185bebc90557e0d611442c8d64f7a0cb7b06f8e156eea37a4a7358f722715be
 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
@@ -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 e480146f49004c818ad93464289761d8a7246b502bd079f8140d0a6f684ebe4e
-R e565d7a955f7dfbceec6b3e9d7245e4b
+P 0c6ab539cfbc908550fa993a587e85d644b6335853ff9781caae860c461c045d
+R 33294cd0e1de3328b05fc8fdf4f59e56
 U dan
-Z 2c7b74af84f6da4d9875b4b1565fc82a
+Z ff4d8e1dd5c81ec2fdd90cee5190a162
index 4b4b64c0bdc7313302f6da22db42412a6c3eb0a1..e5d92301b838bdc09033395146240cdd24508ae6 100644 (file)
@@ -1 +1 @@
-0c6ab539cfbc908550fa993a587e85d644b6335853ff9781caae860c461c045d
\ No newline at end of file
+fdb20e9ee48465b94aa6ac3c5e263ecaa7c3b10f4a193e79f965b7c35944b08b
\ No newline at end of file
index 12a78cde8023caf45375f034fce108378749ee83..31bcb32a0456028f9aa3c96b5608e2ef02dd172b 100644 (file)
@@ -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 */
index 8d899bd1a6e0089649896048e23fab571cf67566..dde845a023cfe1d6b799535ba20ea5bec4754ad8 100644 (file)
@@ -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 */
index e4ea66a725638475c0aa34811c65bc40b7a7c6c4..6a2cc53c66d6de6aa1fd37879b625f50c5f40472 100644 (file)
@@ -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))
index 2d1c64ad130bbd82af83f83e7a04a6fca40726ba..3eb0419b6668a09ee5d51a576b921d1234625c6f 100644 (file)
@@ -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);
index f832e1b01786aed904935c89d1946e2303b9b3e4..78ef82145c2df5911e182522a5e90855514eacc8 100644 (file)
--- 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;
index 02e2bab36053886842a7a19f58427a0f1435a880..d39bb50f3decf308eb5b691d64efb97ac53aeb7b 100644 (file)
--- 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 */
index b5b22d2a821a36412481445923d961405ac465e3..62fb9a47a8a50105f2fe3a8bf84f717dd82c36d1 100644 (file)
@@ -16,10 +16,11 @@ source $testdir/malloc_common.tcl
 set testprefix walseh1
 
 set ::seh_countdown 0 
+set ::seh_errno 10
 proc seh_faultsim_callback {iFault} {
   if {$iFault==650} {
     incr ::seh_countdown -1
-    if {$::seh_countdown==0} { return 1 }
+    if {$::seh_countdown==0} { return $::seh_errno }
   }
   return 0
 }
@@ -31,6 +32,7 @@ proc seh_injectuninstall {} {
   sqlite3_test_control_fault_install
 }
 proc seh_injectstart {iFail} {
+  set ::seh_errno [expr 2+$iFail*10]
   set ::seh_countdown $iFail
 }
 proc seh_injectstop {} {
@@ -47,6 +49,13 @@ set FAULTSIM(seh) [list                   \
   -injectuninstall seh_injectuninstall \
 ]
 
+proc test_system_errno {db expect} {
+  set serrno [sqlite3_system_errno $db]
+  if {$serrno!=$expect} {
+    error "surprising system_errno. Expected $expect, got $serrno"
+  }  
+}
+
 do_execsql_test 1.0 {
   PRAGMA journal_mode = wal;
   CREATE TABLE t1(x, y);
@@ -64,6 +73,7 @@ do_faultsim_test 1 -faults seh -prep {
   execsql { SELECT * FROM t1 } db2
 } -test {
   faultsim_test_result {0 {1 2 3 4}} 
+  if {$testrc} { test_system_errno db2 $::seh_errno }
 }
 catch { db2 close }
 
@@ -76,6 +86,7 @@ do_faultsim_test 2 -faults seh -prep {
   execsql { SELECT * FROM t1 } 
 } -test {
   faultsim_test_result {0 {1 2 3 4}} 
+  if {$testrc} { test_system_errno db $::seh_errno }
 }
 
 do_faultsim_test 3 -faults seh -prep {