diff options
author | drh <drh@noemail.net> | 2016-01-18 00:20:26 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-01-18 00:20:26 +0000 |
commit | dad300d8e1a9e9db9b9be19929e22d6a3c2bcdda (patch) | |
tree | 2820e3c9e3d07ce7425e65ff28d95c5524526e8e /src | |
parent | 3ed7029921c201a6dc9a0861497b782d392ac47c (diff) | |
download | sqlite-dad300d8e1a9e9db9b9be19929e22d6a3c2bcdda.tar.gz sqlite-dad300d8e1a9e9db9b9be19929e22d6a3c2bcdda.zip |
Fix a problem with SQLITE_TEST_REALLOC_STRESS.
FossilOrigin-Name: 0aaf3febb00f622c5ef0853b2491d69f7ca7a21e
Diffstat (limited to 'src')
-rw-r--r-- | src/pragma.c | 16 | ||||
-rw-r--r-- | src/sqliteInt.h | 15 | ||||
-rw-r--r-- | src/vdbe.h | 6 | ||||
-rw-r--r-- | src/vdbeaux.c | 11 |
4 files changed, 33 insertions, 15 deletions
diff --git a/src/pragma.c b/src/pragma.c index 50f7229c3..15f0eecce 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -435,9 +435,9 @@ void sqlite3Pragma( if( !zRight ){ setOneColumnName(v, "cache_size"); pParse->nMem += 2; - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(getCacheSize)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; @@ -688,9 +688,9 @@ void sqlite3Pragma( }; VdbeOp *aOp; int iAddr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(setMeta6)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[2].p2 = iAddr+4; @@ -1732,9 +1732,9 @@ void sqlite3Pragma( { OP_SetCookie, 0, 0, 1}, /* 2 */ }; VdbeOp *aOp; - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(setCookie)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = sqlite3Atoi(zRight); aOp[2].p1 = iDb; @@ -1747,9 +1747,9 @@ void sqlite3Pragma( { OP_ResultRow, 1, 1, 0} }; VdbeOp *aOp; - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(readCookie)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p3 = iCookie; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a70b0cfb3..5d8a504f8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -403,6 +403,21 @@ #endif /* +** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is +** defined. We need to defend against those failures when testing with +** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches +** during a normal build. The following macro can be used to disable tests +** that are always false except when SQLITE_TEST_REALLOC_STRESS is set. +*/ +#if defined(SQLITE_TEST_REALLOC_STRESS) +# define ONLY_IF_REALLOC_STRESS(X) (X) +#elif !defined(NDEBUG) +# define ONLY_IF_REALLOC_STRESS(X) ((X)?(assert(0),1):0) +#else +# define ONLY_IF_REALLOC_STRESS(X) (0) +#endif + +/* ** Declarations used for tracing the operating system interfaces. */ #if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \ diff --git a/src/vdbe.h b/src/vdbe.h index a0ff16d89..f09997bf9 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -180,10 +180,10 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); -#ifdef SQLITE_DEBUG - void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N); +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) + void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); #else -# define sqlite3VdbeVerifyAvailableSpace(A,B) +# define sqlite3VdbeVerifyNoMallocRequired(A,B) #endif VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9859054ba..492a41599 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -607,11 +607,14 @@ int sqlite3VdbeCurrentAddr(Vdbe *p){ /* ** Verify that at least N opcode slots are available in p without -** having to malloc for more space. This interface is used for -** testing only. +** having to malloc for more space (except when compiled using +** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing +** to verify that certain calls to sqlite3VdbeAddOpList() can never +** fail due to a OOM fault and hence that the return value from +** sqlite3VdbeAddOpList() will always be non-NULL. */ -#ifdef SQLITE_DEBUG -void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N){ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ assert( p->nOp + N <= p->pParse->nOpAlloc ); } #endif |