]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem handling a malloc() failure in printf.c. Also some other things to...
authordanielk1977 <danielk1977@noemail.net>
Sat, 1 Sep 2007 09:02:53 +0000 (09:02 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sat, 1 Sep 2007 09:02:53 +0000 (09:02 +0000)
FossilOrigin-Name: 595bfe72f053bc6ecb58bb9044a4cdc53d30b404

manifest
manifest.uuid
src/mem1.c
src/mem2.c
src/printf.c
src/test1.c
src/test6.c
test/main.test
test/printf.test
test/tester.tcl

index 9459cc7f0a5551c62237a37d7784d9d25a5cca5d..5d2e98e01caf0a1155d851d5851be3f30f5d29cf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sfor\sregistration\sof\snon-default\svfs\sobjects.\s(CVS\s4360)
-D 2007-09-01T06:51:28
+C Fix\sa\sproblem\shandling\sa\smalloc()\sfailure\sin\sprintf.c.\sAlso\ssome\sother\sthings\sto\simprove\stest\scoverage.\s(CVS\s4361)
+D 2007-09-01T09:02:54
 F Makefile.in bfcc303429a5d9dcd552d807ee016c77427418c3
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -102,8 +102,8 @@ F src/loadext.c 6894dbbf1666577d957922811620375d6c2f058d
 F src/main.c c271d9104b6bff13d2ddd9a72fcf0926e635a9fd
 F src/malloc.c de4e77fe70a9a0ac47a1c3a874422b107231bf31
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
-F src/mem1.c afe2fbf6d7e8247c6c9f69c1481358b1cad60c08
-F src/mem2.c 20cfac1d521ec74a69eed599baa755f6e905a51f
+F src/mem1.c 9a939c061cc4a94b70b44c23eabf1415df64cc52
+F src/mem2.c b97b4662bf5902cbde0a849c4739e64ce7b07177
 F src/mutex.c 40e5ba09d56863895882a0204d93832e9960ea78
 F src/mutex.h 079fa6fe9da18ceb89e79012c010594c6672addb
 F src/mutex_os2.c d47e9bd495583dd31263d8fe55160a31eb600a3c
@@ -125,7 +125,7 @@ F src/pager.h f204c1a9fe0574953fba89c56d9d9bd1ddfa604a
 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
 F src/pragma.c 363e548dafb52327face8d99757ab56a7b1c1b26
 F src/prepare.c 1506fd279824b1f4bac97514966d0370101f9a6b
-F src/printf.c 81e5db668c211b9b8a9483197d6118b19d76fa74
+F src/printf.c 85f7a4344dda6782a76df43da8e4d5b0342d6b85
 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
 F src/select.c 4706a6115da1bdc09a2be5991168a6cc2c0df267
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
@@ -136,12 +136,12 @@ F src/sqliteInt.h adc8a20e80ccf9eef24cc32f241a3427915a136e
 F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12
 F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
 F src/tclsqlite.c 8db035768623779c97d0509eb88ecbb49c51abca
-F src/test1.c 8fcfb16cbd589f9bb2a21dd19d7cb8ce8141d726
+F src/test1.c e68d0c781b10730cd96f45bca9af36dc00fa10d6
 F src/test2.c 4ab230fbdc0decfa7422f6a052b609ba54f4dfac
 F src/test3.c 199a440ba2b38b26251393b609451a3484a15907
 F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
-F src/test6.c e6ce0d295f524416cb08d30c62c1fb3135962169
+F src/test6.c 0513982dfef4da2a4154b538d2bf538b84ca21d3
 F src/test7.c a9d509d0e9ad214b4772696f49f6e61be26213d1
 F src/test8.c 88e033aefdf5d5522dff46655a14ea7360fb1d26
 F src/test9.c b46c8fe02ac7cca1a7316436d8d38d50c66f4b2f
@@ -344,7 +344,7 @@ F test/lock.test 6825aea0b5885578b1b63a3b178803842c4ee9f1
 F test/lock2.test 5f9557b775662c2a5ee435378f39e10d64f65cb3
 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
 F test/lock4.test 49e22396b9be6e047b3d35469f233be79153c9d5
-F test/main.test e7212ce1023957c7209778cc87fa932bd79ba89a
+F test/main.test 913427b847c6cfba055c9d0629f7479f51ba1a48
 F test/malloc.test 52306f056e7359e68ed2e204f37f47a0e2020c57
 F test/malloc2.test c1a74f46a3581b56df29ff46a4e1c99b41c44ad9
 F test/malloc3.test 39b72b04436a81e0c3d548d195f8bdbf1ebf4b52
@@ -381,7 +381,7 @@ F test/pageropt.test 51e3c091bc2992f5098f7576e3594e1908988939
 F test/pagesize.test e0a8b3fe80f8b8e808d94a00734c7a18c76c407e
 F test/pragma.test b0e73879206934a835856a8b8c4cc884cd8562f3
 F test/pragma2.test bb5aa7be00dae2c381fcc782358048a33c955793
-F test/printf.test 69d8cb0771a1a5e4d9d5dece12fc2c16179ac5e5
+F test/printf.test 13e2887b21f8956cb6c352cf6e6c438cb2f2e55c
 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
 F test/ptrchng.test 1c712dd6516e1377471744fa765e41c79a357da6
 F test/quick.test 88844a19f6d9dc5c990e01c7dd611d33d022a1c1
@@ -420,7 +420,7 @@ F test/table.test dbdfd06aef054ad5aed8e57a782137d57d5c5528
 F test/tableapi.test 036575a98dcce7c92e9f39056839bbad8a715412
 F test/tclsqlite.test a868898e3350246be7ea132621dc25f9835b3030
 F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821
-F test/tester.tcl a18c4ef2233eb87e7717b4578aef3cf6b119993c
+F test/tester.tcl 913a808f05b0aed2fbb16481a423b1a5a118bdf0
 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
 F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb
 F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
@@ -568,7 +568,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 2be8af9d402a5cd8da8c348883188eb38900f6dc
-R 1475678fd3272d043d92d10be839de03
+P 5f48fb95c26a713b3259ee49fd444108030376dc
+R f5d2790ed3ef3229e31edc3fdbdb0ddc
 U danielk1977
-Z 4664902be98fc827f7437460eb18f666
+Z bbe8f7cb92a5a4389623700351cb30a0
index 176f4cdfc9de1908c5e174b5a2d81f2dc155a9ae..1978c9cdccc9dfcd458a4a105a16587688ddcb47 100644 (file)
@@ -1 +1 @@
-5f48fb95c26a713b3259ee49fd444108030376dc
\ No newline at end of file
+595bfe72f053bc6ecb58bb9044a4cdc53d30b404
\ No newline at end of file
index abaafe1ec9dc7f78c3cfbb7be504199d6b8f5895..16001a00916a8579c14329173050d128387d7823 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains the C functions that implement a memory
 ** allocation subsystem for use by SQLite.  
 **
-** $Id: mem1.c,v 1.8 2007/08/24 03:51:34 drh Exp $
+** $Id: mem1.c,v 1.9 2007/09/01 09:02:54 danielk1977 Exp $
 */
 
 /*
@@ -70,16 +70,22 @@ static struct {
  
 } mem;
 
-
 /*
-** Return the amount of memory currently checked out.
+** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
 */
-sqlite3_int64 sqlite3_memory_used(void){
-  sqlite3_int64 n;
+static void enterMem(void){
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
   sqlite3_mutex_enter(mem.mutex);
+}
+
+/*
+** Return the amount of memory currently checked out.
+*/
+sqlite3_int64 sqlite3_memory_used(void){
+  sqlite3_int64 n;
+  enterMutex();
   n = mem.nowUsed;
   sqlite3_mutex_leave(mem.mutex);  
   return n;
@@ -92,10 +98,7 @@ sqlite3_int64 sqlite3_memory_used(void){
 */
 sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
   sqlite3_int64 n;
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
+  enterMutex();
   n = mem.mxUsed;
   if( resetFlag ){
     mem.mxUsed = mem.nowUsed;
@@ -112,10 +115,7 @@ int sqlite3_memory_alarm(
   void *pArg,
   sqlite3_int64 iThreshold
 ){
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
+  enterMutex();
   mem.alarmCallback = xCallback;
   mem.alarmArg = pArg;
   mem.alarmThreshold = iThreshold;
@@ -145,31 +145,27 @@ static void sqlite3MemsysAlarm(int nByte){
 ** Allocate nBytes of memory
 */
 void *sqlite3_malloc(int nBytes){
-  sqlite3_int64 *p;
-  if( nBytes<=0 ){
-    return 0;
-  }
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
-  if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
-    sqlite3MemsysAlarm(nBytes);
-  }
-  p = malloc(nBytes+8);
-  if( p==0 ){
-    sqlite3MemsysAlarm(nBytes);
+  sqlite3_int64 *p = 0;
+  if( nBytes>0 ){
+    enterMutex();
+    if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
+      sqlite3MemsysAlarm(nBytes);
+    }
     p = malloc(nBytes+8);
-  }
-  if( p ){
-    p[0] = nBytes;
-    p++;
-    mem.nowUsed += nBytes;
-    if( mem.nowUsed>mem.mxUsed ){
-      mem.mxUsed = mem.nowUsed;
+    if( p==0 ){
+      sqlite3MemsysAlarm(nBytes);
+      p = malloc(nBytes+8);
     }
+    if( p ){
+      p[0] = nBytes;
+      p++;
+      mem.nowUsed += nBytes;
+      if( mem.nowUsed>mem.mxUsed ){
+        mem.mxUsed = mem.nowUsed;
+      }
+    }
+    sqlite3_mutex_leave(mem.mutex);
   }
-  sqlite3_mutex_leave(mem.mutex);
   return (void*)p; 
 }
 
index afaf010305d44483fa399f24fc948997278c3dcd..830c5dc43f4bcc47d3f1aa7f0f70f42040272ee9 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains the C functions that implement a memory
 ** allocation subsystem for use by SQLite.  
 **
-** $Id: mem2.c,v 1.12 2007/08/30 15:46:07 danielk1977 Exp $
+** $Id: mem2.c,v 1.13 2007/09/01 09:02:54 danielk1977 Exp $
 */
 
 /*
@@ -153,14 +153,21 @@ static struct {
 
 
 /*
-** Return the amount of memory currently checked out.
+** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
 */
-sqlite3_int64 sqlite3_memory_used(void){
-  sqlite3_int64 n;
+static void enterMem(void){
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
   sqlite3_mutex_enter(mem.mutex);
+}
+
+/*
+** Return the amount of memory currently checked out.
+*/
+sqlite3_int64 sqlite3_memory_used(void){
+  sqlite3_int64 n;
+  enterMem();
   n = mem.nowUsed;
   sqlite3_mutex_leave(mem.mutex);  
   return n;
@@ -173,10 +180,7 @@ sqlite3_int64 sqlite3_memory_used(void){
 */
 sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
   sqlite3_int64 n;
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
+  enterMem();
   n = mem.mxUsed;
   if( resetFlag ){
     mem.mxUsed = mem.nowUsed;
@@ -193,10 +197,7 @@ int sqlite3_memory_alarm(
   void *pArg,
   sqlite3_int64 iThreshold
 ){
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
+  enterMem();
   mem.alarmCallback = xCallback;
   mem.alarmArg = pArg;
   mem.alarmThreshold = iThreshold;
@@ -260,82 +261,77 @@ void *sqlite3_malloc(int nByte){
   void **pBt;
   char *z;
   int *pInt;
-  void *p;
+  void *p = 0;
   int totalSize;
 
-  if( nByte<=0 ){
-    mem.iNextIsBenign = 0;
-    return 0;
-  }
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
-  assert( mem.disallow==0 );
-  if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
-    sqlite3MemsysAlarm(nByte);
-  }
-  nByte = (nByte+3)&~3;
-  totalSize = nByte + sizeof(*pHdr) + sizeof(int) +
-               mem.nBacktrace*sizeof(void*) + mem.nTitle;
-  if( mem.iFail>0 ){
-    if( mem.iFail==1 ){
-      p = 0;
-      mem.iFail = mem.iReset;
-      if( mem.iFailCnt==0 ){
-        sqlite3MemsysFailed();  /* A place to set a breakpoint */
-      }
-      mem.iFailCnt++;
-      if( mem.iNextIsBenign ){
-        mem.iBenignFailCnt++;
-      }
-    }else{
-      p = malloc(totalSize);
-      mem.iFail--;
-    }
-  }else{
-    p = malloc(totalSize);
-    if( p==0 ){
+  if( nByte>0 ){
+    enterMem();
+    assert( mem.disallow==0 );
+    if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
       sqlite3MemsysAlarm(nByte);
-      p = malloc(totalSize);
-    }
-  }
-  if( p ){
-    z = p;
-    pBt = (void**)&z[mem.nTitle];
-    pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
-    pHdr->pNext = 0;
-    pHdr->pPrev = mem.pLast;
-    if( mem.pLast ){
-      mem.pLast->pNext = pHdr;
-    }else{
-      mem.pFirst = pHdr;
     }
-    mem.pLast = pHdr;
-    pHdr->iForeGuard = FOREGUARD;
-    pHdr->nBacktraceSlots = mem.nBacktrace;
-    pHdr->nTitle = mem.nTitle;
-    if( mem.nBacktrace ){
-      void *aAddr[40];
-      pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
-      memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
+    nByte = (nByte+3)&~3;
+    totalSize = nByte + sizeof(*pHdr) + sizeof(int) +
+                 mem.nBacktrace*sizeof(void*) + mem.nTitle;
+    if( mem.iFail>0 ){
+      if( mem.iFail==1 ){
+        p = 0;
+        mem.iFail = mem.iReset;
+        if( mem.iFailCnt==0 ){
+          sqlite3MemsysFailed();  /* A place to set a breakpoint */
+        }
+        mem.iFailCnt++;
+        if( mem.iNextIsBenign ){
+          mem.iBenignFailCnt++;
+        }
+      }else{
+        p = malloc(totalSize);
+        mem.iFail--;
+      }
     }else{
-      pHdr->nBacktrace = 0;
-    }
-    if( mem.nTitle ){
-      memcpy(z, mem.zTitle, mem.nTitle);
+      p = malloc(totalSize);
+      if( p==0 ){
+        sqlite3MemsysAlarm(nByte);
+        p = malloc(totalSize);
+      }
     }
-    pHdr->iSize = nByte;
-    pInt = (int*)&pHdr[1];
-    pInt[nByte/sizeof(int)] = REARGUARD;
-    memset(pInt, 0x65, nByte);
-    mem.nowUsed += nByte;
-    if( mem.nowUsed>mem.mxUsed ){
-      mem.mxUsed = mem.nowUsed;
+    if( p ){
+      z = p;
+      pBt = (void**)&z[mem.nTitle];
+      pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
+      pHdr->pNext = 0;
+      pHdr->pPrev = mem.pLast;
+      if( mem.pLast ){
+        mem.pLast->pNext = pHdr;
+      }else{
+        mem.pFirst = pHdr;
+      }
+      mem.pLast = pHdr;
+      pHdr->iForeGuard = FOREGUARD;
+      pHdr->nBacktraceSlots = mem.nBacktrace;
+      pHdr->nTitle = mem.nTitle;
+      if( mem.nBacktrace ){
+        void *aAddr[40];
+        pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
+        memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
+      }else{
+        pHdr->nBacktrace = 0;
+      }
+      if( mem.nTitle ){
+        memcpy(z, mem.zTitle, mem.nTitle);
+      }
+      pHdr->iSize = nByte;
+      pInt = (int*)&pHdr[1];
+      pInt[nByte/sizeof(int)] = REARGUARD;
+      memset(pInt, 0x65, nByte);
+      mem.nowUsed += nByte;
+      if( mem.nowUsed>mem.mxUsed ){
+        mem.mxUsed = mem.nowUsed;
+      }
+      p = (void*)pInt;
     }
-    p = (void*)pInt;
+    sqlite3_mutex_leave(mem.mutex);
   }
-  sqlite3_mutex_leave(mem.mutex);
   mem.iNextIsBenign = 0;
   return p; 
 }
@@ -427,10 +423,7 @@ void sqlite3_memdebug_backtrace(int depth){
 */
 void sqlite3_memdebug_settitle(const char *zTitle){
   int n = strlen(zTitle) + 1;
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
+  enterMem();
   if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
   memcpy(mem.zTitle, zTitle, n);
   mem.zTitle[n] = 0;
index 109e3ad47bfdbcb5870fddb8febce24438392008..bea91e211d27a9576741d313321d3d9ab59392db 100644 (file)
@@ -741,7 +741,7 @@ static void mout(void *arg, const char *zNewText, int nNewChar){
           pM->zText = pM->xRealloc(0, nAlloc);
           if( pM->zText==0 ){
             pM->nAlloc = 0;
-            pM->iMallocFailed = 0;
+            pM->iMallocFailed = 1;
             return;
           }else if( pM->nChar ){
             memcpy(pM->zText, pM->zBase, pM->nChar);
@@ -752,7 +752,7 @@ static void mout(void *arg, const char *zNewText, int nNewChar){
           if( zNew ){
             pM->zText = zNew;
           }else{
-            pM->iMallocFailed = 0;
+            pM->iMallocFailed = 1;
             pM->xRealloc(pM->zText, 0);
             pM->zText = 0;
             pM->nAlloc = 0;
@@ -789,7 +789,8 @@ static char *base_vprintf(
   sM.xRealloc = xRealloc;
   sM.iMallocFailed = 0;
   vxprintf(mout, &sM, useInternal, zFormat, ap);
-  if( xRealloc ){
+  assert(sM.iMallocFailed==0 || sM.zText==0);
+  if( xRealloc && !sM.iMallocFailed ){
     if( sM.zText==sM.zBase ){
       sM.zText = xRealloc(0, sM.nChar+1);
       if( sM.zText ){
index 2802a991bd9b2d0f257c7b3098d019e2761221c5..d98dbed236617e7f2b1bceb2f7db956ff5812fa0 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.272 2007/08/31 17:42:48 danielk1977 Exp $
+** $Id: test1.c,v 1.273 2007/09/01 09:02:54 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -437,7 +437,7 @@ static int test_mprintf_z(
   char *zResult = 0;
   int i;
 
-  for(i=2; i<argc; i++){
+  for(i=2; i<argc && (i==2 || zResult); i++){
     zResult = sqlite3MPrintf(0, "%z%s%s", zResult, argv[1], argv[i]);
   }
   Tcl_AppendResult(interp, zResult, 0);
index 8045509bd9bab7a079ce773ba66bab51cf345cdb..b351303704767c18464e811dd09f3d715dce6f7d 100644 (file)
@@ -698,33 +698,18 @@ static int processDevSymArgs(
 }
 
 /*
-** tclcmd:   sqlite_crashparams ?OPTIONS? DELAY CRASHFILE
-**
-** This procedure implements a TCL command that enables crash testing
-** in testfixture.  Once enabled, crash testing cannot be disabled.
-**
-** Available options are "-characteristics" and "-sectorsize". Both require
-** an argument. For -sectorsize, this is the simulated sector size in
-** bytes. For -characteristics, the argument must be a list of io-capability
-** flags to simulate. Valid flags are "atomic", "atomic512", "atomic1K",
-** "atomic2K", "atomic4K", "atomic8K", "atomic16K", "atomic32K", 
-** "atomic64K", "sequential" and "safe_append".
-**
-** Example:
-**
-**   sqlite_crashparams -sect 1024 -char {atomic sequential} ./test.db 1
+** tclcmd:   sqlite_crash_enable ENABLE
 **
+** Parameter ENABLE must be a boolean value. If true, then the "crash"
+** vfs is added to the system. If false, it is removed.
 */
-static int crashParamsObjCmd(
+static int crashEnableCmd(
   void * clientData,
   Tcl_Interp *interp,
   int objc,
   Tcl_Obj *CONST objv[]
 ){
-  int iDelay;
-  const char *zCrashFile;
-  int nCrashFile, iDc, iSectorSize;
-
+  int isEnable;
   static sqlite3_vfs crashVfs = {
     1,                  /* iVersion */
     0,                  /* szOsFile */
@@ -747,6 +732,18 @@ static int crashParamsObjCmd(
     cfCurrentTime         /* xCurrentTime */
   };
 
+  if( objc!=2 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "ENABLE");
+    return TCL_ERROR;
+  }
+
+  if( Tcl_GetBooleanFromObj(interp, objv[1], &isEnable) ){
+    return TCL_ERROR;
+  }
+
+  if( (isEnable && crashVfs.pAppData) || (!isEnable && !crashVfs.pAppData) ){
+    return TCL_OK;
+  }
 
   if( crashVfs.pAppData==0 ){
     sqlite3_vfs *pOriginalVfs = sqlite3_vfs_find(0);
@@ -754,8 +751,42 @@ static int crashParamsObjCmd(
     crashVfs.pAppData = (void *)pOriginalVfs;
     crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile;
     sqlite3_vfs_register(&crashVfs, 0);
+  }else{
+    crashVfs.pAppData = 0;
+    sqlite3_vfs_unregister(&crashVfs);
   }
 
+  return TCL_OK;
+}
+
+/*
+** tclcmd:   sqlite_crashparams ?OPTIONS? DELAY CRASHFILE
+**
+** This procedure implements a TCL command that enables crash testing
+** in testfixture.  Once enabled, crash testing cannot be disabled.
+**
+** Available options are "-characteristics" and "-sectorsize". Both require
+** an argument. For -sectorsize, this is the simulated sector size in
+** bytes. For -characteristics, the argument must be a list of io-capability
+** flags to simulate. Valid flags are "atomic", "atomic512", "atomic1K",
+** "atomic2K", "atomic4K", "atomic8K", "atomic16K", "atomic32K", 
+** "atomic64K", "sequential" and "safe_append".
+**
+** Example:
+**
+**   sqlite_crashparams -sect 1024 -char {atomic sequential} ./test.db 1
+**
+*/
+static int crashParamsObjCmd(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  int iDelay;
+  const char *zCrashFile;
+  int nCrashFile, iDc, iSectorSize;
+
   iDc = -1;
   iSectorSize = -1;
 
@@ -826,6 +857,7 @@ static int devSymObjCmd(
 */
 int Sqlitetest6_Init(Tcl_Interp *interp){
 #ifndef SQLITE_OMIT_DISKIO
+  Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
   Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
   Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
 #endif
index 85bca73c4bc6a796e8a022902fd7d8aa47f4bfeb..c788164cde768970483d1821980ec5d33e6fa581 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is exercising the code in main.c.
 #
-# $Id: main.test,v 1.25 2006/02/09 22:24:41 drh Exp $
+# $Id: main.test,v 1.26 2007/09/01 09:02:54 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -315,5 +315,42 @@ do_test main-3.6 {
   catchsql {SELECT 'abc' + #9}
 } {1 {near "#9": syntax error}}
 
+# The following test-case tests the linked list code used to manage
+# sqlite3_vfs structures.
+do_test main-4.1 {
+  sqlite3_crash_enable 1
+  sqlite3_crash_enable 0
+
+  sqlite3async_enable 1
+  sqlite3async_enable 0
+
+  sqlite3_crash_enable 1
+  sqlite3async_enable 1
+  sqlite3_crash_enable 0
+  sqlite3async_enable 0
+
+  sqlite3_crash_enable 1
+  sqlite3async_enable 1
+  sqlite3async_enable 0
+  sqlite3_crash_enable 0
+
+  sqlite3async_enable 1
+  sqlite3_crash_enable 1
+  sqlite3_crash_enable 0
+  sqlite3async_enable 0
+
+  sqlite3async_enable 1
+  sqlite3_crash_enable 1
+  sqlite3async_enable 0
+  sqlite3_crash_enable 0
+} {}
+do_test main-4.2 {
+  set rc [catch {sqlite3 db test.db -vfs crash} msg]
+  list $rc $msg
+} {1 {no such vfs: crash}}
+do_test main-4.3 {
+  set rc [catch {sqlite3 db test.db -vfs async} msg]
+  list $rc $msg
+} {1 {no such vfs: async}}
 
 finish_test
index fa1255a6c671af770ee0daa00a80bb8f2aeeccb2..9f37d30c1fcfd954c1a9266ab7c7bcd547714f27 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the sqlite_*_printf() interface.
 #
-# $Id: printf.test,v 1.24 2007/05/10 17:23:12 drh Exp $
+# $Id: printf.test,v 1.25 2007/09/01 09:02:54 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -293,4 +293,28 @@ do_test printf-15.3 {
   sqlite3_snprintf_int 0 {} 0
 } {abcdefghijklmnopqrstuvwxyz}
 
+# Now test malloc() failure within a sqlite3_mprintf():
+#
+foreach var {a b c d} {
+  set $var [string repeat $var 400]
+}
+
+set str1 "[string repeat A 360]%d%d%s"
+set str2 [string repeat B 5000]
+set zSuccess "[string repeat A 360]11[string repeat B 5000]"
+foreach ::iRepeat {0 1} {
+  set nTestNum 1
+  while {1} {
+    sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat
+    set z [sqlite3_mprintf_str $str1 1 1 $str2]
+    set nFail [sqlite3_memdebug_fail -1 -benign nBenign]
+    do_test printf-malloc-$::iRepeat.$nTestNum {
+      expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)}
+    } {1}
+    if {$nFail == 0} break
+    incr nTestNum
+  }
+}
+
 finish_test
+
index 4fcc17a13d26c68af173ea514d06bc3724334b74..a1ca65c480def1d7a69910f877d94deb9155b5de 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements some common TCL routines used for regression
 # testing the SQLite library
 #
-# $Id: tester.tcl,v 1.90 2007/09/01 06:51:28 danielk1977 Exp $
+# $Id: tester.tcl,v 1.91 2007/09/01 09:02:54 danielk1977 Exp $
 
 
 set tcl_precision 15
@@ -356,6 +356,7 @@ proc crashsql {args} {
   set cfile [file join [pwd] $crashfile]
 
   set f [open crash.tcl w]
+  puts $f "sqlite3_crash_enable 1"
   puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
   puts $f "set sqlite_pending_byte $::sqlite_pending_byte"
   puts $f "sqlite3 db test.db -vfs crash"