aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-01-18 00:20:26 +0000
committerdrh <drh@noemail.net>2016-01-18 00:20:26 +0000
commitdad300d8e1a9e9db9b9be19929e22d6a3c2bcdda (patch)
tree2820e3c9e3d07ce7425e65ff28d95c5524526e8e /src
parent3ed7029921c201a6dc9a0861497b782d392ac47c (diff)
downloadsqlite-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.c16
-rw-r--r--src/sqliteInt.h15
-rw-r--r--src/vdbe.h6
-rw-r--r--src/vdbeaux.c11
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