1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

All of the malloc test cases run. Still seeing failures in malloc4.test. (CVS 4272)

FossilOrigin-Name: 205d0b881d541db65837ce6cf44d58d607635bc2
This commit is contained in:
drh
2007-08-22 22:04:37 +00:00
parent f3a65f7e44
commit ed138fb3bc
18 changed files with 216 additions and 677 deletions

View File

@ -1,5 +1,5 @@
C The\smalloc.test\sscript\snow\spasses\sall\stests\swith\sno\serrors.\s(CVS\s4271) C All\sof\sthe\smalloc\stest\scases\srun.\s\sStill\sseeing\sfailures\sin\smalloc4.test.\s(CVS\s4272)
D 2007-08-22T20:18:22 D 2007-08-22T22:04:37
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -102,7 +102,7 @@ F src/main.c 527f27c74d22d83713abbd1550fd5a4ecce89aca
F src/malloc.c 8078d4c3f9217c0bb018e432d8655c14996bb107 F src/malloc.c 8078d4c3f9217c0bb018e432d8655c14996bb107
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c 7b023d45dd71944414db469c742457239e24d74d F src/mem1.c 7b023d45dd71944414db469c742457239e24d74d
F src/mem2.c b707e02fec2cf4d6fce8427d640e90d5003afe9e F src/mem2.c 28a0d9306378f97e5cddb7863cb3893d40d1f885
F src/mutex.c 9cf641f556a4119ef90ed41b82f2d5647f81686e F src/mutex.c 9cf641f556a4119ef90ed41b82f2d5647f81686e
F src/os.c d8f029317c95dcd2887b9f0f154281cdfbd303ad F src/os.c d8f029317c95dcd2887b9f0f154281cdfbd303ad
F src/os.h 399c89cafa93b9ef35c3dc70f77644d10936b535 F src/os.h 399c89cafa93b9ef35c3dc70f77644d10936b535
@ -115,7 +115,7 @@ F src/os_unix.c 3e1ce27aa8364f92881a285820ffa414539a6b1b
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c 29c0e19c1072679a4c7818c49fab2f35d2ad7747 F src/os_win.c 29c0e19c1072679a4c7818c49fab2f35d2ad7747
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c 029a441236e9f504e25a3e2d2944afeae48c297c F src/pager.c 54087a81a44e38e30cf8bfed41a73acc9ece84a8
F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8 F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5 F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5
@ -146,7 +146,7 @@ F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
F src/test_config.c f0b911bb615d93a192647e76910dce65cbbcf3ad F src/test_config.c f0b911bb615d93a192647e76910dce65cbbcf3ad
F src/test_hexio.c 82916f918687502658f02533b519c38cb180db6d F src/test_hexio.c 82916f918687502658f02533b519c38cb180db6d
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
F src/test_malloc.c d9ba6be85f9c4a439b19f6e0a72d91c369d72c63 F src/test_malloc.c 1e24e6bf8dfff1886b57b353911493e7025c2158
F src/test_md5.c 34599caee5b1c73dcf86ca31f55846fab8c19ef7 F src/test_md5.c 34599caee5b1c73dcf86ca31f55846fab8c19ef7
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
F src/test_server.c 319f6b1a99bab5f7149387442243d6e65a8ab4eb F src/test_server.c 319f6b1a99bab5f7149387442243d6e65a8ab4eb
@ -339,18 +339,18 @@ F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
F test/lock4.test 49e22396b9be6e047b3d35469f233be79153c9d5 F test/lock4.test 49e22396b9be6e047b3d35469f233be79153c9d5
F test/main.test e7212ce1023957c7209778cc87fa932bd79ba89a F test/main.test e7212ce1023957c7209778cc87fa932bd79ba89a
F test/malloc.test dbfaedfca734283182db18a64416cf037c33648f F test/malloc.test dbfaedfca734283182db18a64416cf037c33648f
F test/malloc2.test 4ed7d719542c4570dec9c2ebe2bbdf3a9f3b0d05 F test/malloc2.test 96dfa6318d3b7bcd41d4fe7e24d35196d465bf58
F test/malloc3.test e965954b6f808876a63d3101fd70370320b509a7 F test/malloc3.test 65d323508c7c4e1fb5569d03a11070b0259ad2fe
F test/malloc4.test 59cd02f71b363302a04c4e77b97c0a1572eaa210 F test/malloc4.test 3f4857ca83168c00900221681fc76de04394968a
F test/malloc5.test 90b1f1ce9f835e6d14fb01be1452169b21d12818 F test/malloc5.test 6f7b96f1bea181d789a7140fd3fabfb0e333d8f5
F test/malloc6.test 025ae0b78542e0ddd000d23f79d93e9be9ba0f15 F test/malloc6.test 3733b9bd4e039c3239f869c40edbb88172025e2e
F test/malloc7.test 1cf52834509eac7ebeb92105dacd4669f9ca9869 F test/malloc7.test dd66d8f82916becf1d29b6640e4f4855485570f8
F test/malloc8.test e4054ca2a87ab1d42255bec009b177ba20b5a487 F test/malloc8.test 5ff95278bc73e815e295971afcdd175f6ba19258
F test/malloc9.test 8381041fd89c31fba60c8a1a1c776bb022108572 F test/malloc9.test fb99833476bc1a9b0b15573b9a56ae13af843ef9
F test/mallocA.test 525674e6e0775a9bf85a33f1da1c6bbddc712c30 F test/mallocA.test f49b8df5e1d2a090830ef5a5f94174c3c930234b
F test/mallocB.test 5d4a3dc4931a8c13ef3723c4934af23ff9d60d71 F test/mallocB.test 56fd615f3fea97180132a89dd1dd2068852ef6a0
F test/mallocC.test e470e03fe8b28d79f0a5123601a9653331cc7226 F test/mallocC.test b6b83dea1c3820a70d50b0378481b71bda44bcb3
F test/malloc_common.tcl 7b59db5f0617678f4e5af3a7b3715a1dacd1b8e2 F test/malloc_common.tcl 4f07ce6b4a542cc7052e26543406bca439a863f5
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8 F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893 F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893
F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217 F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
@ -412,7 +412,7 @@ F test/table.test dbdfd06aef054ad5aed8e57a782137d57d5c5528
F test/tableapi.test 036575a98dcce7c92e9f39056839bbad8a715412 F test/tableapi.test 036575a98dcce7c92e9f39056839bbad8a715412
F test/tclsqlite.test 593f3b30221e85786965d9e5670ae4f96b4e4159 F test/tclsqlite.test 593f3b30221e85786965d9e5670ae4f96b4e4159
F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821 F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821
F test/tester.tcl e72b0b8e1b1d9cf20bc641793a3d3c5442a5bbb3 F test/tester.tcl c9cd05b488392bde9e7e8044d988943a4a52f1fe
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
@ -559,7 +559,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P b6399dff1370449912391cc5925bdc468b5dade0 P db818430e9ea4ef4a4af575784009d5acae785a3
R 3ea0ebd7e3bb257a718fe4ade9660d28 R 5826e29b4eff86308f2e435b216e5a67
U drh U drh
Z 59e51dd8c4f548815477ba78b815fe4b Z 50c7b8ba17910d7b90bf428d2ab32765

View File

@ -1 +1 @@
db818430e9ea4ef4a4af575784009d5acae785a3 205d0b881d541db65837ce6cf44d58d607635bc2

View File

@ -12,7 +12,7 @@
** This file contains the C functions that implement a memory ** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite. ** allocation subsystem for use by SQLite.
** **
** $Id: mem2.c,v 1.6 2007/08/22 20:18:22 drh Exp $ ** $Id: mem2.c,v 1.7 2007/08/22 22:04:37 drh Exp $
*/ */
/* /*
@ -454,6 +454,15 @@ int sqlite3_memdebug_fail(int iFail, int iRepeat){
return n; return n;
} }
/*
** This routine returns the number of successful mallocs remaining until
** the next simulated malloc failure. -1 is returned if no simulated
** failure is currently scheduled.
*/
int sqlite3_memdebug_pending(void){
return mem.iFail-1;
}
/* /*
** The following two routines are used to assert that no memory ** The following two routines are used to assert that no memory
** allocations occur between one call and the next. The use of ** allocations occur between one call and the next. The use of

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** another is writing.
** **
** @(#) $Id: pager.c,v 1.367 2007/08/22 18:54:33 danielk1977 Exp $ ** @(#) $Id: pager.c,v 1.368 2007/08/22 22:04:37 drh Exp $
*/ */
#ifndef SQLITE_OMIT_DISKIO #ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h" #include "sqliteInt.h"
@ -538,7 +538,9 @@ static int pageInStatement(PgHdr *pPg){
static void pager_resize_hash_table(Pager *pPager, int N){ static void pager_resize_hash_table(Pager *pPager, int N){
PgHdr **aHash, *pPg; PgHdr **aHash, *pPg;
assert( N>0 && (N&(N-1))==0 ); assert( N>0 && (N&(N-1))==0 );
pagerLeave(pPager);
aHash = sqlite3MallocZero( sizeof(aHash[0])*N ); aHash = sqlite3MallocZero( sizeof(aHash[0])*N );
pagerEnter(pPager);
if( aHash==0 ){ if( aHash==0 ){
/* Failure to rehash is not an error. It is only a performance hit. */ /* Failure to rehash is not an error. It is only a performance hit. */
return; return;
@ -2873,7 +2875,7 @@ int sqlite3PagerReleaseMemory(int nReq){
Pager *pPager = sqlite3PagerList; Pager *pPager = sqlite3PagerList;
for( ; pPager && (nReq<0 || nReleased<nReq); pPager=pPager->pNext){ for( ; pPager && (nReq<0 || nReleased<nReq); pPager=pPager->pNext){
PgHdr *pPg; PgHdr *pPg;
int rc; int rc = SQLITE_OK;
/* In-memory databases should not appear on the pager list */ /* In-memory databases should not appear on the pager list */
assert( !MEMDB ); assert( !MEMDB );
@ -2885,7 +2887,10 @@ int sqlite3PagerReleaseMemory(int nReq){
** calling fsync() if this is the first iteration of the outermost ** calling fsync() if this is the first iteration of the outermost
** loop). ** loop).
*/ */
while( SQLITE_OK==(rc = pager_recycle(pPager, i, &pPg)) && pPg) { while( (nReq<0 || nReleased<nReq) &&
SQLITE_OK==(rc = pager_recycle(pPager, i, &pPg)) &&
pPg
) {
/* We've found a page to free. At this point the page has been /* We've found a page to free. At this point the page has been
** removed from the page hash-table, free-list and synced-list ** removed from the page hash-table, free-list and synced-list
** (pFirstSynced). It is still in the all pages (pAll) list. ** (pFirstSynced). It is still in the all pages (pAll) list.
@ -3163,9 +3168,11 @@ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){
goto pager_allocate_out; goto pager_allocate_out;
} }
} }
pagerLeave(pPager);
pPg = sqlite3_malloc( sizeof(*pPg) + pPager->pageSize pPg = sqlite3_malloc( sizeof(*pPg) + pPager->pageSize
+ sizeof(u32) + pPager->nExtra + sizeof(u32) + pPager->nExtra
+ MEMDB*sizeof(PgHistory) ); + MEMDB*sizeof(PgHistory) );
pagerEnter(pPager);
if( pPg==0 ){ if( pPg==0 ){
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
goto pager_allocate_out; goto pager_allocate_out;
@ -3486,7 +3493,9 @@ static int pager_open_journal(Pager *pPager){
assert( pPager->useJournal ); assert( pPager->useJournal );
assert( pPager->aInJournal==0 ); assert( pPager->aInJournal==0 );
sqlite3PagerPagecount(pPager); sqlite3PagerPagecount(pPager);
pagerLeave(pPager);
pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 );
pagerEnter(pPager);
if( pPager->aInJournal==0 ){ if( pPager->aInJournal==0 ){
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
goto failed_to_open_journal; goto failed_to_open_journal;
@ -3610,7 +3619,9 @@ int sqlite3PagerBegin(DbPage *pPg, int exFlag){
assert( pPager->origDbSize==0 ); assert( pPager->origDbSize==0 );
assert( pPager->aInJournal==0 ); assert( pPager->aInJournal==0 );
sqlite3PagerPagecount(pPager); sqlite3PagerPagecount(pPager);
pagerLeave(pPager);
pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 );
pagerEnter(pPager);
if( !pPager->aInJournal ){ if( !pPager->aInJournal ){
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
}else{ }else{
@ -4439,7 +4450,9 @@ static int pagerStmtBegin(Pager *pPager){
return SQLITE_OK; return SQLITE_OK;
} }
assert( pPager->journalOpen ); assert( pPager->journalOpen );
pagerLeave(pPager);
pPager->aInStmt = sqlite3MallocZero( pPager->dbSize/8 + 1 ); pPager->aInStmt = sqlite3MallocZero( pPager->dbSize/8 + 1 );
pagerEnter(pPager);
if( pPager->aInStmt==0 ){ if( pPager->aInStmt==0 ){
/* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */
return SQLITE_NOMEM; return SQLITE_NOMEM;

View File

@ -13,7 +13,7 @@
** This file contains code used to implement test interfaces to the ** This file contains code used to implement test interfaces to the
** memory allocation subsystem. ** memory allocation subsystem.
** **
** $Id: test_malloc.c,v 1.2 2007/08/15 20:41:29 drh Exp $ ** $Id: test_malloc.c,v 1.3 2007/08/22 22:04:37 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@ -228,7 +228,7 @@ static int test_memdebug_dump(
/* /*
** Usage: sqlite3_memdebug_fail COUNTER REPEAT ** Usage: sqlite3_memdebug_fail COUNTER ?REPEAT?
** **
** Arrange for a simulated malloc() failure after COUNTER successes. ** Arrange for a simulated malloc() failure after COUNTER successes.
** If REPEAT is 1 then all subsequent malloc()s fail. If REPEAT is ** If REPEAT is 1 then all subsequent malloc()s fail. If REPEAT is
@ -249,12 +249,16 @@ static int test_memdebug_fail(
int iFail; int iFail;
int iRepeat; int iRepeat;
int nFail = 0; int nFail = 0;
if( objc!=3 ){ if( objc!=3 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "COUNTER REPEAT"); Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?REPEAT?");
return TCL_ERROR; return TCL_ERROR;
} }
if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR;
if( objc==3 ){
if( Tcl_GetIntFromObj(interp, objv[2], &iRepeat) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &iRepeat) ) return TCL_ERROR;
}else{
iRepeat = -1;
}
#ifdef SQLITE_MEMDEBUG #ifdef SQLITE_MEMDEBUG
{ {
extern int sqlite3_memdebug_fail(int,int); extern int sqlite3_memdebug_fail(int,int);
@ -266,6 +270,25 @@ static int test_memdebug_fail(
} }
/*
** Usage: sqlite3_memdebug_pending
**
** Return the number of successful mallocs remaining before the
** next simulated failure. Return -1 if no simulated failure is
** currently scheduled.
*/
static int test_memdebug_pending(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
extern int sqlite3_memdebug_pending(void);
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_pending()));
return TCL_OK;
}
/* /*
** Register commands with the TCL interpreter. ** Register commands with the TCL interpreter.
*/ */
@ -282,6 +305,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "sqlite3_memdebug_backtrace", test_memdebug_backtrace }, { "sqlite3_memdebug_backtrace", test_memdebug_backtrace },
{ "sqlite3_memdebug_dump", test_memdebug_dump }, { "sqlite3_memdebug_dump", test_memdebug_dump },
{ "sqlite3_memdebug_fail", test_memdebug_fail }, { "sqlite3_memdebug_fail", test_memdebug_fail },
{ "sqlite3_memdebug_pending", test_memdebug_pending },
}; };
int i; int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){

View File

@ -8,23 +8,23 @@
# May you share freely, never taking more than you give. # May you share freely, never taking more than you give.
# #
#*********************************************************************** #***********************************************************************
#
# This file attempts to check that the library can recover from a malloc() # This file attempts to check that the library can recover from a malloc()
# failure when sqlite3_global_recover() is invoked. # failure when sqlite3_global_recover() is invoked.
# #
# $Id: malloc2.test,v 1.5 2006/09/04 18:54:14 drh Exp $ # (Later:) The sqlite3_global_recover() interface is now a no-op.
# Recovery from malloc() failures is automatic. But we keep these
# tests around because you can never have too many test cases.
#
# $Id: malloc2.test,v 1.6 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG=1" puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test
return
}
ifcapable !globalrecover {
finish_test finish_test
return return
} }
@ -65,7 +65,7 @@ proc do_malloc2_test {tn args} {
# Run the SQL. Malloc number $::n is set to fail. A malloc() failure # Run the SQL. Malloc number $::n is set to fail. A malloc() failure
# may or may not be reported. # may or may not be reported.
sqlite_malloc_fail $::n sqlite3_memdebug_fail $::n 1
do_test malloc2-$tn.$::n.2 { do_test malloc2-$tn.$::n.2 {
set res [catchsql [string trim $::mallocopts(-sql)]] set res [catchsql [string trim $::mallocopts(-sql)]]
set rc [expr { set rc [expr {
@ -80,10 +80,8 @@ proc do_malloc2_test {tn args} {
# If $::n is greater than the number of malloc() calls required to # If $::n is greater than the number of malloc() calls required to
# execute the SQL, then this test is finished. Break out of the loop. # execute the SQL, then this test is finished. Break out of the loop.
if {[lindex [sqlite_malloc_stat] 2]>0} { set nFail [sqlite3_memdebug_fail -1 -1]
sqlite_malloc_fail -1 if {$nFail==0} break
break
}
# Nothing should work now, because the allocator should refuse to # Nothing should work now, because the allocator should refuse to
# allocate any memory. # allocate any memory.

View File

@ -13,13 +13,14 @@
# correctly. The emphasis of these tests are the _prepare(), _step() and # correctly. The emphasis of these tests are the _prepare(), _step() and
# _finalize() calls. # _finalize() calls.
# #
# $Id: malloc3.test,v 1.10 2007/03/28 01:59:34 drh Exp $ # $Id: malloc3.test,v 1.11 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} { #
ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
@ -559,7 +560,7 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
set ::rollback_hook_count 0 set ::rollback_hook_count 0
set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit
sqlite_malloc_fail $iFail sqlite3_memdebug_fail $iFail 1
set rc [catch {db eval [lindex $v 1]} msg] ;# True error occurs set rc [catch {db eval [lindex $v 1]} msg] ;# True error occurs
set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit
@ -574,11 +575,12 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
} {1} } {1}
} }
set nFail [sqlite3_memdebug_fail -1 -1]
if {$rc == 0} { if {$rc == 0} {
# Successful execution of sql. Our "mallocs-until-failure" # Successful execution of sql. Our "mallocs-until-failure"
# count should be greater than 0. Otherwise a malloc() failed # count should be greater than 0. Otherwise a malloc() failed
# and the error was not reported. # and the error was not reported.
if {[lindex [sqlite_malloc_stat] 2] <= 0} { if {$nFail>0} {
error "Unreported malloc() failure" error "Unreported malloc() failure"
} }
@ -591,7 +593,6 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
incr pc incr pc
set iFail 1 set iFail 1
sqlite_malloc_fail 0
integrity_check "malloc3-(integrity).$iterid" integrity_check "malloc3-(integrity).$iterid"
} elseif {[regexp {.*out of memory} $msg]} { } elseif {[regexp {.*out of memory} $msg]} {
# Out of memory error, as expected # Out of memory error, as expected
@ -638,9 +639,7 @@ db cache size 0
run_test $::run_test_script 9 1 run_test $::run_test_script 9 1
# run_test [lrange $::run_test_script 0 3] 0 63 # run_test [lrange $::run_test_script 0 3] 0 63
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1 -1
db close db close
pp_check_for_leaks
finish_test finish_test

View File

@ -12,7 +12,7 @@
# This file contains tests to ensure that the library handles malloc() failures # This file contains tests to ensure that the library handles malloc() failures
# correctly. The emphasis in this file is on sqlite3_column_XXX() APIs. # correctly. The emphasis in this file is on sqlite3_column_XXX() APIs.
# #
# $Id: malloc4.test,v 1.3 2006/01/23 07:52:41 danielk1977 Exp $ # $Id: malloc4.test,v 1.4 2007/08/22 22:04:37 drh Exp $
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR # NOTES ON EXPECTED BEHAVIOUR
@ -27,7 +27,7 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} { if {[info command sqlite3_memdebug_pending]==""} {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
@ -42,7 +42,7 @@ proc do_stmt_test {id sql} {
set ::sql $sql set ::sql $sql
set go 1 set go 1
for {set n 1} {$go} {incr n} { for {set n 1} {$go} {incr n} {
set testid "malloc4-$id.(iFail $n)" set testid "malloc4-$id.$n"
# Prepare the statement # Prepare the statement
do_test ${testid}.1 { do_test ${testid}.1 {
@ -51,7 +51,7 @@ proc do_stmt_test {id sql} {
} {1} } {1}
# Set the Nth malloc() to fail. # Set the Nth malloc() to fail.
sqlite_malloc_fail $n sqlite3_memdebug_fail $n 1
# Test malloc failure in the _name(), _name16(), decltype() and # Test malloc failure in the _name(), _name16(), decltype() and
# decltype16() APIs. Calls that occur after the malloc() failure should # decltype16() APIs. Calls that occur after the malloc() failure should
@ -69,26 +69,26 @@ proc do_stmt_test {id sql} {
# about explicitly testing them. # about explicitly testing them.
# #
do_test ${testid}.2.1 { do_test ${testid}.2.1 {
set mf1 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set mf1 [expr [sqlite3_memdebug_pending] <= 0]
set ::name8 [sqlite3_column_name $::STMT 0] set ::name8 [sqlite3_column_name $::STMT 0]
set mf2 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set mf2 [expr [sqlite3_memdebug_pending] <= 0]
expr {$mf1 == $mf2 || $::name8 == ""} expr {$mf1 == $mf2 || $::name8 == ""}
} {1} } {1}
do_test ${testid}.2.2 { do_test ${testid}.2.2 {
set mf1 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set mf1 [expr [sqlite3_memdebug_pending] <= 0]
set ::name16 [sqlite3_column_name16 $::STMT 0] set ::name16 [sqlite3_column_name16 $::STMT 0]
set ::name16 [encoding convertfrom unicode $::name16] set ::name16 [encoding convertfrom unicode $::name16]
set ::name16 [string range $::name16 0 end-1] set ::name16 [string range $::name16 0 end-1]
set mf2 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set mf2 [expr [sqlite3_memdebug_pending] <= 0]
expr {$mf1 == $mf2 || $::name16 == ""} expr {$mf1 == $mf2 || $::name16 == ""}
} {1} } {1}
do_test ${testid}.2.3 { do_test ${testid}.2.3 {
set mf1 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set mf1 [expr [sqlite3_memdebug_pending] <= 0]
set ::name8_2 [sqlite3_column_name $::STMT 0] set ::name8_2 [sqlite3_column_name $::STMT 0]
set mf2 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set mf2 [expr [sqlite3_memdebug_pending] <= 0]
expr {$mf1 == $mf2 || $::name8_2 == ""} expr {$mf1 == $mf2 || $::name8_2 == ""}
} {1} } {1}
set ::mallocFailed [expr [lindex [sqlite_malloc_stat] 2] <= 0] set ::mallocFailed [expr [sqlite3_memdebug_pending] <= 0]
do_test ${testid}.2.4 { do_test ${testid}.2.4 {
expr { expr {
$::name8 == $::name8_2 && $::name16 == $::name8 && !$::mallocFailed || $::name8 == $::name8_2 && $::name16 == $::name8 && !$::mallocFailed ||
@ -102,30 +102,30 @@ proc do_stmt_test {id sql} {
# running sqlite3_step(), make sure that malloc() is not about to fail. # running sqlite3_step(), make sure that malloc() is not about to fail.
# Memory allocation failures that occur within sqlite3_step() are tested # Memory allocation failures that occur within sqlite3_step() are tested
# elsewhere. # elsewhere.
set mf [lindex [sqlite_malloc_stat] 2] set mf [sqlite3_memdebug_pending]
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
do_test ${testid}.3 { do_test ${testid}.3 {
sqlite3_step $::STMT sqlite3_step $::STMT
} {SQLITE_ROW} } {SQLITE_ROW}
sqlite_malloc_fail $mf sqlite3_memdebug_fail $mf
# Test for malloc() failures within _text() and _text16(). # Test for malloc() failures within _text() and _text16().
# #
do_test ${testid}.4.1 { do_test ${testid}.4.1 {
set ::text8 [sqlite3_column_text $::STMT 0] set ::text8 [sqlite3_column_text $::STMT 0]
set mf [expr [lindex [sqlite_malloc_stat] 2] <= 0 && !$::mallocFailed] set mf [expr [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed]
expr {$mf==0 || $::text8 == ""} expr {$mf==0 || $::text8 == ""}
} {1} } {1}
do_test ${testid}.4.2 { do_test ${testid}.4.2 {
set ::text16 [sqlite3_column_text16 $::STMT 0] set ::text16 [sqlite3_column_text16 $::STMT 0]
set ::text16 [encoding convertfrom unicode $::text16] set ::text16 [encoding convertfrom unicode $::text16]
set ::text16 [string range $::text16 0 end-1] set ::text16 [string range $::text16 0 end-1]
set mf [expr [lindex [sqlite_malloc_stat] 2] <= 0 && !$::mallocFailed] set mf [expr [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed]
expr {$mf==0 || $::text16 == ""} expr {$mf==0 || $::text16 == ""}
} {1} } {1}
do_test ${testid}.4.3 { do_test ${testid}.4.3 {
set ::text8_2 [sqlite3_column_text $::STMT 0] set ::text8_2 [sqlite3_column_text $::STMT 0]
set mf [expr [lindex [sqlite_malloc_stat] 2] <= 0 && !$::mallocFailed] set mf [expr [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed]
expr {$mf==0 || $::text8_2 == "" || ($::text16 == "" && $::text8 != "")} expr {$mf==0 || $::text8_2 == "" || ($::text16 == "" && $::text8 != "")}
} {1} } {1}
@ -133,33 +133,33 @@ proc do_stmt_test {id sql} {
# way this can occur is if the string has to be translated from UTF-16 to # way this can occur is if the string has to be translated from UTF-16 to
# UTF-8 before being converted to a numeric value. # UTF-8 before being converted to a numeric value.
do_test ${testid}.4.4.1 { do_test ${testid}.4.4.1 {
set mf [lindex [sqlite_malloc_stat] 2] set mf [sqlite3_memdebug_pending]
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
sqlite3_column_text16 $::STMT 0 sqlite3_column_text16 $::STMT 0
sqlite_malloc_fail $mf sqlite3_memdebug_fail $mf
sqlite3_column_int $::STMT 0 sqlite3_column_int $::STMT 0
} {0} } {0}
do_test ${testid}.4.5 { do_test ${testid}.4.5 {
set mf [lindex [sqlite_malloc_stat] 2] set mf [sqlite3_memdebug_pending]
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
sqlite3_column_text16 $::STMT 0 sqlite3_column_text16 $::STMT 0
sqlite_malloc_fail $mf sqlite3_memdebug_fail $mf
sqlite3_column_int64 $::STMT 0 sqlite3_column_int64 $::STMT 0
} {0} } {0}
do_test ${testid}.4.6 { do_test ${testid}.4.6 {
set mf [lindex [sqlite_malloc_stat] 2] set mf [sqlite3_memdebug_pending]
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
sqlite3_column_text16 $::STMT 0 sqlite3_column_text16 $::STMT 0
sqlite_malloc_fail $mf sqlite3_memdebug_fail $mf
sqlite3_column_double $::STMT 0 sqlite3_column_double $::STMT 0
} {0.0} } {0.0}
set mallocFailedAfterStep [expr \ set mallocFailedAfterStep [expr \
[lindex [sqlite_malloc_stat] 2] <= 0 && !$::mallocFailed [sqlite3_memdebug_pending] <= 0 && !$::mallocFailed
] ]
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
# Test that if a malloc() failed the next call to sqlite3_step() returns # Test that if a malloc() failed the next call to sqlite3_step() returns
# SQLITE_ERROR. If malloc() did not fail, it should return SQLITE_DONE. # SQLITE_ERROR. If malloc() did not fail, it should return SQLITE_DONE.
# #
@ -172,7 +172,7 @@ proc do_stmt_test {id sql} {
} [expr {$mallocFailedAfterStep ? "SQLITE_NOMEM" : "SQLITE_OK"}] } [expr {$mallocFailedAfterStep ? "SQLITE_NOMEM" : "SQLITE_OK"}]
if {$::mallocFailed == 0 && $mallocFailedAfterStep == 0} { if {$::mallocFailed == 0 && $mallocFailedAfterStep == 0} {
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
set go 0 set go 0
} }
} }
@ -189,6 +189,5 @@ execsql {
do_stmt_test 1 "SELECT * FROM tbl" do_stmt_test 1 "SELECT * FROM tbl"
sqlite_malloc_fail 0 sqlite3_memdebug_fail -1
finish_test finish_test

View File

@ -12,7 +12,7 @@
# This file contains test cases focused on the two memory-management APIs, # This file contains test cases focused on the two memory-management APIs,
# sqlite3_soft_heap_limit() and sqlite3_release_memory(). # sqlite3_soft_heap_limit() and sqlite3_release_memory().
# #
# $Id: malloc5.test,v 1.12 2007/08/12 20:07:59 drh Exp $ # $Id: malloc5.test,v 1.13 2007/08/22 22:04:37 drh Exp $
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR # NOTES ON EXPECTED BEHAVIOUR
@ -25,7 +25,8 @@ source $testdir/tester.tcl
db close db close
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} { #
ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
@ -174,7 +175,7 @@ do_test malloc5-3.2 {
} {1 2 3 4 5 6 7 8 9 10 11 12} } {1 2 3 4 5 6 7 8 9 10 11 12}
db2 close db2 close
sqlite_malloc_outstanding -clearmaxbytes puts "Highwater mark: [sqlite3_memory_highwater]"
# The following two test cases each execute a transaction in which # The following two test cases each execute a transaction in which
# 10000 rows are inserted into table abc. The first test case is used # 10000 rows are inserted into table abc. The first test case is used
@ -198,22 +199,22 @@ do_test malloc5-4.1 {
execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');" execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');"
} }
execsql {COMMIT;} execsql {COMMIT;}
set ::nMaxBytes [sqlite_malloc_outstanding -maxbytes] set nMaxBytes [sqlite3_memory_highwater 1]
if {$::nMaxBytes==""} {set ::nMaxBytes 1000001} puts -nonewline " (Highwater mark: $nMaxBytes) "
expr $::nMaxBytes > 1000000 expr $nMaxBytes > 1000000
} {1} } {1}
do_test malloc5-4.2 { do_test malloc5-4.2 {
sqlite3_release_memory sqlite3_release_memory
sqlite_malloc_outstanding -clearmaxbytes
sqlite3_soft_heap_limit 100000 sqlite3_soft_heap_limit 100000
sqlite3_memory_highwater 1
execsql {BEGIN;} execsql {BEGIN;}
for {set i 0} {$i < 10000} {incr i} { for {set i 0} {$i < 10000} {incr i} {
execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');" execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');"
} }
execsql {COMMIT;} execsql {COMMIT;}
set ::nMaxBytes [sqlite_malloc_outstanding -maxbytes] set nMaxBytes [sqlite3_memory_highwater 1]
if {$::nMaxBytes==""} {set ::nMaxBytes 0} puts -nonewline " (Highwater mark: $nMaxBytes) "
expr $::nMaxBytes <= 100000 expr $nMaxBytes <= 100000
} {1} } {1}
do_test malloc5-4.3 { do_test malloc5-4.3 {
# Check that the content of table abc is at least roughly as expected. # Check that the content of table abc is at least roughly as expected.

View File

@ -9,122 +9,24 @@
# #
#*********************************************************************** #***********************************************************************
# This file attempts to check the library in an out-of-memory situation. # This file attempts to check the library in an out-of-memory situation.
# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This
# special feature is used to see what happens in the library if a malloc
# were to really fail due to an out-of-memory situation.
# #
# $Id: malloc6.test,v 1.1 2006/06/26 12:50:09 drh Exp $ # $Id: malloc6.test,v 1.2 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
source $testdir/malloc_common.tcl
# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
# -sqlprep SQL script to run to prepare test.
# -tclbody TCL script to run with malloc failure simulation.
# -sqlbody TCL script to run with malloc failure simulation.
# -cleanup TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test malloc6-$tn.$::n {
# Remove all traces of database files test.db and test2.db from the files
# system. Then open (empty database) "test.db" with the handle [db].
#
sqlite_malloc_fail 0
catch {db close}
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
catch {file delete -force test2.db}
catch {file delete -force test2.db-journal}
catch {sqlite3 db test.db}
set ::DB [sqlite3_connection_pointer db]
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite_malloc_fail $::n
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
# If the test fails (if $v!=0) and the database connection actually
# exists, make sure the failure code is SQLITE_NOMEM.
if {$v && [info command db]=="db" && [info exists ::mallocopts(-sqlbody)]
&& [db errorcode]!=7} {
set v 999
}
set leftover [lindex [sqlite_malloc_stat] 2]
if {$leftover>0} {
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
set ::go 0
if {$v} {
puts "\nError message returned: $msg"
} else {
set v {1 1}
}
} else {
set v2 [expr {$msg=="" || $msg=="out of memory"}]
if {!$v2} {puts "\nError message returned: $msg"}
lappend v $v2
}
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
unset ::mallocopts
}
set sqlite_os_trace 0 set sqlite_os_trace 0
do_malloc_test 1 -tclprep { do_malloc_test malloc6-1 -tclprep {
db close db close
} -tclbody { } -tclbody {
if {[catch {sqlite3 db test.db}]} { if {[catch {sqlite3 db test.db}]} {
@ -149,5 +51,4 @@ do_test malloc6-1.X {
set sqlite_open_file_count set sqlite_open_file_count
} {0} } {0}
sqlite_malloc_fail 0
finish_test finish_test

View File

@ -11,130 +11,33 @@
# This file contains additional out-of-memory checks (see malloc.tcl) # This file contains additional out-of-memory checks (see malloc.tcl)
# added to expose a bug in out-of-memory handling for sqlite3_prepare16(). # added to expose a bug in out-of-memory handling for sqlite3_prepare16().
# #
# $Id: malloc7.test,v 1.2 2006/07/26 14:57:30 drh Exp $ # $Id: malloc7.test,v 1.3 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
source $testdir/malloc_common.tcl
# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
# -sqlprep SQL script to run to prepare test.
# -tclbody TCL script to run with malloc failure simulation.
# -sqlbody TCL script to run with malloc failure simulation.
# -cleanup TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1 do_malloc_test malloc7-1 -sqlprep {
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test malloc7-$tn.$::n {
# Remove all traces of database files test.db and test2.db from the files
# system. Then open (empty database) "test.db" with the handle [db].
#
sqlite_malloc_fail 0
catch {db close}
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
catch {file delete -force test2.db}
catch {file delete -force test2.db-journal}
catch {sqlite3 db test.db}
set ::DB [sqlite3_connection_pointer db]
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite_malloc_fail $::n
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
# If the test fails (if $v!=0) and the database connection actually
# exists, make sure the failure code is SQLITE_NOMEM.
if {$v && [info command db]=="db" && [info exists ::mallocopts(-sqlbody)]
&& [db errorcode]!=7} {
set v 999
}
set leftover [lindex [sqlite_malloc_stat] 2]
if {$leftover>0} {
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
set ::go 0
if {$v} {
puts "\nError message returned: $msg"
} else {
set v {1 1}
}
} else {
set v2 [expr {$msg=="" || $msg=="out of memory"}]
if {!$v2} {puts "\nError message returned: $msg"}
lappend v $v2
}
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
unset ::mallocopts
}
db eval {
CREATE TABLE t1(a,b,c,d); CREATE TABLE t1(a,b,c,d);
CREATE INDEX i1 ON t1(b,c); CREATE INDEX i1 ON t1(b,c);
} } -tclbody {
do_malloc_test 1 -tclbody {
set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"]
append sql16 "\00\00" append sql16 "\00\00"
set nbyte [string length $sql16] set nbyte [string length $sql16]
set ::STMT [sqlite3_prepare16 $::DB $sql16 $nbyte DUMMY] set ::STMT [sqlite3_prepare16 db $sql16 $nbyte DUMMY]
sqlite3_finalize $::STMT sqlite3_finalize $::STMT
} }
# Ensure that no file descriptors were leaked. # Ensure that no file descriptors were leaked.
do_test malloc-99.X { do_test malloc-99.X {
catch {db close} catch {db close}
@ -142,5 +45,4 @@ do_test malloc-99.X {
} {0} } {0}
puts open-file-count=$sqlite_open_file_count puts open-file-count=$sqlite_open_file_count
sqlite_malloc_fail 0
finish_test finish_test

View File

@ -11,107 +11,20 @@
# This file contains additional out-of-memory checks (see malloc.tcl) # This file contains additional out-of-memory checks (see malloc.tcl)
# added to expose a bug in out-of-memory handling for sqlite3_value_text() # added to expose a bug in out-of-memory handling for sqlite3_value_text()
# #
# $Id: malloc8.test,v 1.3 2007/05/07 19:31:17 drh Exp $ # $Id: malloc8.test,v 1.4 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
# Usage: do_malloc_test <test number> <options...> source $testdir/malloc_common.tcl
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
# -sqlprep SQL script to run to prepare test.
# -tclbody TCL script to run with malloc failure simulation.
# -sqlbody TCL script to run with malloc failure simulation.
# -cleanup TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test malloc8-$tn.$::n {
sqlite_malloc_fail 0
catch {db close}
sqlite3 db test.db
set ::DB [sqlite3_connection_pointer db]
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite_malloc_fail $::n
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
# If the test fails (if $v!=0) and the database connection actually
# exists, make sure the failure code is SQLITE_NOMEM.
if {$v && [info command db]=="db" && [info exists ::mallocopts(-sqlbody)]
&& [db errorcode]!=7} {
set v 999
}
set leftover [lindex [sqlite_malloc_stat] 2]
if {$leftover>0} {
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
set ::go 0
if {$v} {
puts "\nError message returned: $msg"
} else {
set v {1 1}
}
} else {
set v2 [expr {$msg=="" || $msg=="out of memory"}]
if {!$v2} {puts "\nError message returned: $msg"}
lappend v $v2
}
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
unset ::mallocopts
}
# The setup is a database with UTF-16 encoding that contains a single # The setup is a database with UTF-16 encoding that contains a single
# large string. We will be running lots of queries against this # large string. We will be running lots of queries against this
@ -120,34 +33,54 @@ proc do_malloc_test {tn args} {
# to fail and for sqlite3_value_text() to return 0 even though # to fail and for sqlite3_value_text() to return 0 even though
# sqlite3_value_type() returns SQLITE_TEXT. # sqlite3_value_type() returns SQLITE_TEXT.
# #
db close
file delete -force test.db test.db-journal do_malloc_test malloc8-1 -sqlprep {
sqlite3 db test.db
db eval {
PRAGMA encoding='UTF-16'; PRAGMA encoding='UTF-16';
CREATE TABLE t1(a); CREATE TABLE t1(a);
INSERT INTO t1 INSERT INTO t1
VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'); VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ');
} } -sqlbody {
do_malloc_test 1 -sqlbody {
SELECT lower(a), upper(a), quote(a), trim(a), trim('x',a) FROM t1; SELECT lower(a), upper(a), quote(a), trim(a), trim('x',a) FROM t1;
} }
do_malloc_test 2 -sqlbody { do_malloc_test malloc8-2 -sqlprep {
PRAGMA encoding='UTF-16';
CREATE TABLE t1(a);
INSERT INTO t1
VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ');
} -sqlbody {
SELECT replace(a,'x','y'), replace('x',a,'y'), replace('x','y',a) SELECT replace(a,'x','y'), replace('x',a,'y'), replace('x','y',a)
FROM t1; FROM t1;
} }
do_malloc_test 3 -sqlbody { do_malloc_test malloc8-3 -sqlprep {
PRAGMA encoding='UTF-16';
CREATE TABLE t1(a);
INSERT INTO t1
VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ');
} -sqlbody {
SELECT length(a), substr(a, 4, 4) FROM t1; SELECT length(a), substr(a, 4, 4) FROM t1;
} }
do_malloc_test 4 -sqlbody { do_malloc_test malloc8-4 -sqlprep {
PRAGMA encoding='UTF-16';
CREATE TABLE t1(a);
INSERT INTO t1
VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ');
} -sqlbody {
SELECT julianday(a,a) FROM t1; SELECT julianday(a,a) FROM t1;
} }
do_malloc_test 5 -sqlbody { do_malloc_test malloc8-5 -sqlprep {
PRAGMA encoding='UTF-16';
CREATE TABLE t1(a);
INSERT INTO t1
VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ');
} -sqlbody {
SELECT 1 FROM t1 WHERE a LIKE 'hello' ESCAPE NULL; SELECT 1 FROM t1 WHERE a LIKE 'hello' ESCAPE NULL;
} }
do_malloc_test 6 -sqlbody { do_malloc_test malloc8-6 -sqlprep {
PRAGMA encoding='UTF-16';
CREATE TABLE t1(a);
INSERT INTO t1
VALUES('0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ');
} -sqlbody {
SELECT hex(randomblob(100)); SELECT hex(randomblob(100));
} }
@ -157,5 +90,4 @@ do_test malloc-99.X {
set sqlite_open_file_count set sqlite_open_file_count
} {0} } {0}
sqlite_malloc_fail 0
finish_test finish_test

View File

@ -11,110 +11,20 @@
# This file contains additional out-of-memory checks (see malloc.tcl) # This file contains additional out-of-memory checks (see malloc.tcl)
# added to expose a bug in out-of-memory handling for sqlite3_prepare(). # added to expose a bug in out-of-memory handling for sqlite3_prepare().
# #
# $Id: malloc9.test,v 1.1 2007/04/30 21:39:16 drh Exp $ # $Id: malloc9.test,v 1.2 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
# Usage: do_malloc_test <test number> <options...> source $testdir/malloc_common.tcl
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
# -sqlprep SQL script to run to prepare test.
# -tclbody TCL script to run with malloc failure simulation.
# -sqlbody TCL script to run with malloc failure simulation.
# -cleanup TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test malloc9-$tn.$::n {
sqlite_malloc_fail 0
catch {db close}
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
sqlite3 db test.db
set ::DB [sqlite3_connection_pointer db]
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite_malloc_fail $::n
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
# If the test fails (if $v!=0) and the database connection actually
# exists, make sure the failure code is SQLITE_NOMEM.
if {$v && [info command db]=="db" && [info exists ::mallocopts(-sqlbody)]
&& [db errorcode]!=7} {
set v 999
}
set leftover [lindex [sqlite_malloc_stat] 2]
if {$leftover>0} {
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
set ::go 0
if {$v} {
puts "\nError message returned: $msg"
} else {
set v {1 1}
}
} else {
set v2 [expr {$msg=="" || [regexp {out of memory} $msg]}]
if {!$v2} {puts "\nError message returned: $msg"}
lappend v $v2
}
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
unset ::mallocopts
}
do_malloc_test 1 -tclprep { do_malloc_test 1 -tclprep {
set sql {CREATE TABLE t1(x)} set sql {CREATE TABLE t1(x)}
@ -138,5 +48,4 @@ do_test malloc-99.X {
set sqlite_open_file_count set sqlite_open_file_count
} {0} } {0}
sqlite_malloc_fail 0
finish_test finish_test

View File

@ -10,109 +10,20 @@
#*********************************************************************** #***********************************************************************
# This file contains additional out-of-memory checks (see malloc.tcl). # This file contains additional out-of-memory checks (see malloc.tcl).
# #
# $Id: mallocA.test,v 1.2 2007/05/12 15:00:15 drh Exp $ # $Id: mallocA.test,v 1.3 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
# Usage: do_malloc_test <test number> <options...> source $testdir/malloc_common.tcl
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
# -sqlprep SQL script to run to prepare test.
# -tclbody TCL script to run with malloc failure simulation.
# -sqlbody TCL script to run with malloc failure simulation.
# -cleanup TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test mallocA-$tn.$::n {
sqlite_malloc_fail 0
catch {db close}
catch {file delete -force test.db test.db-journal}
catch {file copy test.db.bu test.db}
sqlite3 db test.db
set ::DB [sqlite3_connection_pointer db]
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite_malloc_fail $::n
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
# If the test fails (if $v!=0) and the database connection actually
# exists, make sure the failure code is SQLITE_NOMEM.
if {$v && [info command db]=="db" && [info exists ::mallocopts(-sqlbody)]
&& [db errorcode]!=7} {
set v 999
}
set leftover [lindex [sqlite_malloc_stat] 2]
if {$leftover>0} {
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
set ::go 0
if {$v} {
puts "\nError message returned: $msg"
} else {
set v {1 1}
}
} else {
set v2 [expr {$msg=="" || [regexp {out of memory} $msg]}]
if {!$v2} {puts "\nError message returned: $msg"}
lappend v $v2
}
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
unset ::mallocopts
}
# Construct a test database # Construct a test database
# #
@ -128,22 +39,21 @@ db eval {
} }
db close db close
file copy test.db test.db.bu file copy test.db test.db.bu
sqlite3 db test.db
do_malloc_test 1 -sqlbody { do_malloc_test 1 -testdb test.db.bu -sqlbody {
ANALYZE ANALYZE
} }
do_malloc_test 2 -sqlbody { do_malloc_test 2 -testdb test.db.bu -sqlbody {
REINDEX; REINDEX;
} }
do_malloc_test 3 -sqlbody { do_malloc_test 3 -testdb test.db.bu -sqlbody {
REINDEX t1; REINDEX t1;
} }
do_malloc_test 4 -sqlbody { do_malloc_test 4 -testdb test.db.bu -sqlbody {
REINDEX main.t1; REINDEX main.t1;
} }
do_malloc_test 5 -sqlbody { do_malloc_test 5 -testdb test.db.bu -sqlbody {
REINDEX nocase; REINDEX nocase;
} }
@ -154,5 +64,4 @@ do_test malloc-99.X {
} {0} } {0}
file delete -force test.db.bu file delete -force test.db.bu
sqlite_malloc_fail 0
finish_test finish_test

View File

@ -13,7 +13,7 @@
# that they have little in common. # that they have little in common.
# #
# #
# $Id: mallocB.test,v 1.3 2007/07/26 06:50:06 danielk1977 Exp $ # $Id: mallocB.test,v 1.4 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -21,11 +21,12 @@ source $testdir/malloc_common.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
source $testdir/malloc_common.tcl
do_malloc_test mallocB-1 -sqlbody {SELECT - 456} do_malloc_test mallocB-1 -sqlbody {SELECT - 456}
do_malloc_test mallocB-2 -sqlbody {SELECT - 456.1} do_malloc_test mallocB-2 -sqlbody {SELECT - 456.1}
@ -41,5 +42,4 @@ do_malloc_test mallocB-5 -sqlbody {SELECT * FROM (SELECT 1) GROUP BY 1;}
# #
do_malloc_test mallocB-6 -sqlbody { SELECT test_auxdata('hello world'); } do_malloc_test mallocB-6 -sqlbody { SELECT test_auxdata('hello world'); }
sqlite_malloc_fail 0
finish_test finish_test

View File

@ -12,15 +12,15 @@
# This file tests aspects of the malloc failure while parsing # This file tests aspects of the malloc failure while parsing
# CREATE TABLE statements in auto_vacuum mode. # CREATE TABLE statements in auto_vacuum mode.
# #
# $Id: mallocC.test,v 1.2 2007/08/13 12:58:18 drh Exp $ # $Id: mallocC.test,v 1.3 2007/08/22 22:04:37 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on. # Only run these tests if memory debugging is turned on.
# #
if {[info command sqlite_malloc_stat]==""} { ifcapable !memdebug {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG=1" puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test finish_test
return return
} }
@ -61,7 +61,7 @@ proc do_mallocC_test {tn args} {
# Run the SQL. Malloc number $::n is set to fail. A malloc() failure # Run the SQL. Malloc number $::n is set to fail. A malloc() failure
# may or may not be reported. # may or may not be reported.
sqlite_malloc_fail $::n sqlite3_memdebug_fail $::n 1
do_test mallocC-$tn.$::n.1 { do_test mallocC-$tn.$::n.1 {
set res [catchsql [string trim $::mallocopts(-sql)]] set res [catchsql [string trim $::mallocopts(-sql)]]
set rc [expr { set rc [expr {
@ -76,8 +76,8 @@ proc do_mallocC_test {tn args} {
# If $::n is greater than the number of malloc() calls required to # If $::n is greater than the number of malloc() calls required to
# execute the SQL, then this test is finished. Break out of the loop. # execute the SQL, then this test is finished. Break out of the loop.
if {[lindex [sqlite_malloc_stat] 2]>0} { set nFail [sqlite3_memdebug_fail -1 -1]
sqlite_malloc_fail -1 if {$nFail==0} {
break break
} }

View File

@ -48,6 +48,9 @@ proc do_malloc_test {tn args} {
catch {file delete -force test.db-journal} catch {file delete -force test.db-journal}
catch {file delete -force test2.db} catch {file delete -force test2.db}
catch {file delete -force test2.db-journal} catch {file delete -force test2.db-journal}
if {[info exists ::mallocopts(-testdb)]} {
file copy $::mallocopts(-testdb) test.db
}
catch {sqlite3 db test.db} catch {sqlite3 db test.db}
# Execute any -tclprep and -sqlprep scripts. # Execute any -tclprep and -sqlprep scripts.

View File

@ -11,7 +11,7 @@
# This file implements some common TCL routines used for regression # This file implements some common TCL routines used for regression
# testing the SQLite library # testing the SQLite library
# #
# $Id: tester.tcl,v 1.85 2007/08/22 20:18:22 drh Exp $ # $Id: tester.tcl,v 1.86 2007/08/22 22:04:37 drh Exp $
# Make sure tclsqlite3 was compiled correctly. Abort now with an # Make sure tclsqlite3 was compiled correctly. Abort now with an
# error message if not. # error message if not.
@ -192,9 +192,6 @@ proc finalize_testing {} {
catch {db2 close} catch {db2 close}
catch {db3 close} catch {db3 close}
catch {
pp_check_for_leaks
}
sqlite3 db {} sqlite3 db {}
# sqlite3_clear_tsd_memdebug # sqlite3_clear_tsd_memdebug
db close db close
@ -571,63 +568,6 @@ proc copy_file {from to} {
} }
} }
# This command checks for outstanding calls to sqlite3_malloc()
# A list is returned with one entry for each outstanding
# malloc. Each list entry is itself a list of 5 items, as follows:
#
# { <number-bytes> <file-name> <line-number> <test-case> <stack-dump> }
#
proc check_for_leaks {} {
set ret [list]
set cnt 0
foreach alloc [sqlite_malloc_outstanding] {
foreach {nBytes file iLine userstring backtrace} $alloc {}
set stack [list]
set skip 0
# The first command in this block will probably fail on windows. This
# means there will be no stack dump available.
if {$cnt < 25 && $backtrace!=""} {
catch {
set stuff [eval "exec addr2line -e ./testfixture -f $backtrace"]
foreach {func line} $stuff {
if {$func != "??" || $line != "??:0"} {
regexp {.*/(.*)} $line dummy line
lappend stack "${func}() $line"
} else {
if {[lindex $stack end] != "..."} {
lappend stack "..."
}
}
}
}
incr cnt
}
if {!$skip} {
lappend ret [list $nBytes $file $iLine $userstring $stack]
}
}
return $ret
}
# Pretty print a report based on the return value of [check_for_leaks] to
# stdout.
proc pp_check_for_leaks {} {
set l [check_for_leaks]
set n 0
foreach leak $l {
foreach {nBytes file iLine userstring stack} $leak {}
puts "$nBytes bytes leaked at $file:$iLine ($userstring)"
foreach frame $stack {
puts " $frame"
}
incr n $nBytes
}
puts "Memory leaked: $n bytes in [llength $l] allocations"
puts ""
}
# If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set
# to non-zero, then set the global variable $AUTOVACUUM to 1. # to non-zero, then set the global variable $AUTOVACUUM to 1.
set AUTOVACUUM $sqlite_options(default_autovacuum) set AUTOVACUUM $sqlite_options(default_autovacuum)