diff --git a/manifest b/manifest index 9459cc7f0a..5d2e98e01c 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 176f4cdfc9..1978c9cdcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f48fb95c26a713b3259ee49fd444108030376dc \ No newline at end of file +595bfe72f053bc6ecb58bb9044a4cdc53d30b404 \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index abaafe1ec9..16001a0091 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -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; +/* +** Enter the mutex mem.mutex. Allocate it if it is not already allocated. +*/ +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; - if( mem.mutex==0 ){ - mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); - } - sqlite3_mutex_enter(mem.mutex); + 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); - p = malloc(nBytes+8); - } - if( p ){ - p[0] = nBytes; - p++; - mem.nowUsed += nBytes; - if( mem.nowUsed>mem.mxUsed ){ - mem.mxUsed = mem.nowUsed; + 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==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; } diff --git a/src/mem2.c b/src/mem2.c index afaf010305..830c5dc43f 100644 --- a/src/mem2.c +++ b/src/mem2.c @@ -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); + } + 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 ){ + 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*)); + }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; + } + sqlite3_mutex_leave(mem.mutex); } - 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; - } - 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; diff --git a/src/printf.c b/src/printf.c index 109e3ad47b..bea91e211d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -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 ){ diff --git a/src/test1.c b/src/test1.c index 2802a991bd..d98dbed236 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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; imxPathname; + 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 ** @@ -725,37 +787,6 @@ static int crashParamsObjCmd( const char *zCrashFile; int nCrashFile, iDc, iSectorSize; - static sqlite3_vfs crashVfs = { - 1, /* iVersion */ - 0, /* szOsFile */ - 0, /* mxPathname */ - 0, /* pNext */ - "crash", /* zName */ - 0, /* pAppData */ - - cfOpen, /* xOpen */ - cfDelete, /* xDelete */ - cfAccess, /* xAccess */ - cfGetTempName, /* xGetTempName */ - cfFullPathname, /* xFullPathname */ - cfDlOpen, /* xDlOpen */ - cfDlError, /* xDlError */ - cfDlSym, /* xDlSym */ - cfDlClose, /* xDlClose */ - cfRandomness, /* xRandomness */ - cfSleep, /* xSleep */ - cfCurrentTime /* xCurrentTime */ - }; - - - if( crashVfs.pAppData==0 ){ - sqlite3_vfs *pOriginalVfs = sqlite3_vfs_find(0); - crashVfs.mxPathname = pOriginalVfs->mxPathname; - crashVfs.pAppData = (void *)pOriginalVfs; - crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile; - sqlite3_vfs_register(&crashVfs, 0); - } - 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 diff --git a/test/main.test b/test/main.test index 85bca73c4b..c788164cde 100644 --- a/test/main.test +++ b/test/main.test @@ -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 diff --git a/test/printf.test b/test/printf.test index fa1255a6c6..9f37d30c1f 100644 --- a/test/printf.test +++ b/test/printf.test @@ -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 + diff --git a/test/tester.tcl b/test/tester.tcl index 4fcc17a13d..a1ca65c480 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -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"