mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix a problem handling a malloc() failure in printf.c. Also some other things to improve test coverage. (CVS 4361)
FossilOrigin-Name: 595bfe72f053bc6ecb58bb9044a4cdc53d30b404
This commit is contained in:
26
manifest
26
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
|
||||
|
@ -1 +1 @@
|
||||
5f48fb95c26a713b3259ee49fd444108030376dc
|
||||
595bfe72f053bc6ecb58bb9044a4cdc53d30b404
|
68
src/mem1.c
68
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;
|
||||
}
|
||||
|
||||
|
165
src/mem2.c
165
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;
|
||||
|
@ -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 ){
|
||||
|
@ -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);
|
||||
|
94
src/test6.c
94
src/test6.c
@ -697,6 +697,68 @@ static int processDevSymArgs(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 crashEnableCmd(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int isEnable;
|
||||
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( 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);
|
||||
crashVfs.mxPathname = pOriginalVfs->mxPathname;
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
Reference in New Issue
Block a user