-C Patch\sto\smemsubsys1.test\sin\sorder\sto\savoid\sa\ssegfault\sin\stableapi.test.\s(CVS\s5252)
-D 2008-06-20T00:03:22
+C Move\s(almost\sall)\smalloc\sfailure\stest\slogic\sfrom\sfault.c\sto\stest_malloc.c.\s(CVS\s5253)
+D 2008-06-20T11:05:38
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in ff6f90048555a0088f6a4b7406bed5e55a7c4eff
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/date.c e841168e5520bbbb2a1cbcdce7531d8b23017b4d
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
-F src/fault.c 34d0f93490a659561a5a41bccb40cc1ef918d265
+F src/fault.c dd9ec1b83759b105014bfc831f4b59894af306e9
F src/func.c 1e7d9569570134ac0771a00382d9d4b41c4aa052
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df
F src/loadext.c 40024a0f476c1279494876b9a002001b29e5d3e3
-F src/main.c ae01b4e90c6a323b689dea1e0af4bf98dc484c7f
+F src/main.c 194909a1f45283961f6f6143338600bb8727d3f1
F src/malloc.c 66c0b17a6611547f630b6ea67e14e575b9431507
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
F src/mem1.c 159f10e280f2d9aea597cf938851e61652dd5c3d
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
F src/sqlite.h.in bf94fcce7c2da5e92d0037595238efbb4f5d0985
F src/sqlite3ext.h f162a72daef5ebf8b211fe8c0ec96e85d22fbf9b
-F src/sqliteInt.h 4d4c0432b5f4918beff36a075015b32244c420c3
+F src/sqliteInt.h 1d2417d1ac2280cb1557413bd6f0200cc87b7d28
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
F src/status.c 6cb10377992505bd69f1ca1d75c1240a65f25a58
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
F src/test_func.c f4aafa10f17d52c43a64b47717265802e6e552b3
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
F src/test_loadext.c df8ab3a6481ddebbdf0d28ebac5d9e0790f7860f
-F src/test_malloc.c 8c8c0b5cad66b1cb5b8ccca6efec1739572a5978
+F src/test_malloc.c cc4111e1f87f99e40a23809cbb2af7d53207b5c1
F src/test_md5.c 28209a4e2068711b5443c33104fe41f21d160071
F src/test_mutex.c 8cfe5c56d5583e07c25c50f59c42ca0104dd24bb
F src/test_onefile.c 1f87d4a21cbfb24a7c35e4333fa0bd34d641f68d
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 9b04e10f6c00c36652444206d1d8868a560eb56e
-R 1d236634be0294388a5fbf26bd78c134
-U drh
-Z 98968f4980c50e00172f902ce8864e91
+P 62411a6e605ec50d8d61233d753cd2ad65c2218d
+R 1627595575a0bf69b485a06e6fd086c3
+U danielk1977
+Z 99658609f6d63a203a5b4c43c3642af7
-62411a6e605ec50d8d61233d753cd2ad65c2218d
\ No newline at end of file
+4ae21e3419ad7e69dd735ca45fdc5a2de93d1840
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This file contains code to implement a fault-injector used for
-** testing and verification of SQLite.
**
-** Subsystems within SQLite can call sqlite3FaultStep() to see if
-** they should simulate a fault. sqlite3FaultStep() normally returns
-** zero but will return non-zero if a fault should be simulated.
-** Fault injectors can be used, for example, to simulate memory
-** allocation failures or I/O errors.
+** This file contains code to support the concept of "benign"
+** malloc failures.
**
-** The fault injector is omitted from the code if SQLite is
-** compiled with -DSQLITE_OMIT_BUILTIN_TEST=1. There is a very
-** small performance hit for leaving the fault injector in the code.
-** Commerical products will probably want to omit the fault injector
-** from production builds. But safety-critical systems who work
-** under the motto "fly what you test and test what you fly" may
-** choose to leave the fault injector enabled even in production.
-**
-** $Id: fault.c,v 1.7 2008/06/19 18:17:50 danielk1977 Exp $
-*/
-#include "sqliteInt.h"
-
-/*
-** There can be various kinds of faults. For example, there can be
-** a memory allocation failure. Or an I/O failure. For each different
-** fault type, there is a separate FaultInjector structure to keep track
-** of the status of that fault.
+** $Id: fault.c,v 1.8 2008/06/20 11:05:38 danielk1977 Exp $
*/
-static struct MemFault {
- int iCountdown; /* Number of pending successes before we hit a failure */
- int nRepeat; /* Number of times to repeat the failure */
- int nBenign; /* Number of benign failures seen since last config */
- int nFail; /* Number of failures seen since last config */
- u8 enable; /* True if enabled */
- i16 benign; /* Positive if next failure will be benign */
-
- int isInstalled;
- sqlite3_mem_methods m; /* 'Real' malloc implementation */
-} memfault;
-/*
-** This routine exists as a place to set a breakpoint that will
-** fire on any simulated malloc() failure.
-*/
-static void sqlite3Fault(void){
- static int cnt = 0;
- cnt++;
-}
-
-/*
-** Check to see if a fault should be simulated. Return true to simulate
-** the fault. Return false if the fault should not be simulated.
-*/
-static int faultsimStep(){
- if( likely(!memfault.enable) ){
- return 0;
- }
- if( memfault.iCountdown>0 ){
- memfault.iCountdown--;
- return 0;
- }
- sqlite3Fault();
- memfault.nFail++;
- if( memfault.benign>0 ){
- memfault.nBenign++;
- }
- memfault.nRepeat--;
- if( memfault.nRepeat<=0 ){
- memfault.enable = 0;
- }
- return 1;
-}
-
-static void *faultsimMalloc(int n){
- void *p = 0;
- if( !faultsimStep() ){
- p = memfault.m.xMalloc(n);
- }
- return p;
-}
-
-
-static void *faultsimRealloc(void *pOld, int n){
- void *p = 0;
- if( !faultsimStep() ){
- p = memfault.m.xRealloc(pOld, n);
- }
- return p;
-}
-
-/*
-** The following method calls are passed directly through to the underlying
-** malloc system:
-**
-** xFree
-** xSize
-** xRoundup
-** xInit
-** xShutdown
-*/
-static void faultsimFree(void *p){
- memfault.m.xFree(p);
-}
-static int faultsimSize(void *p){
- return memfault.m.xSize(p);
-}
-static int faultsimRoundup(int n){
- return memfault.m.xRoundup(n);
-}
-static int faultsimInit(void *p){
- return memfault.m.xInit(memfault.m.pAppData);
-}
-static void faultsimShutdown(void *p){
- memfault.m.xShutdown(memfault.m.pAppData);
-}
-
-/*
-** This routine configures and enables a fault injector. After
-** calling this routine, a FaultStep() will return false (zero)
-** nDelay times, then it will return true nRepeat times,
-** then it will again begin returning false.
-*/
-void sqlite3FaultConfig(int id, int nDelay, int nRepeat){
- memfault.iCountdown = nDelay;
- memfault.nRepeat = nRepeat;
- memfault.nBenign = 0;
- memfault.nFail = 0;
- memfault.enable = nDelay>=0;
- memfault.benign = 0;
-}
+#include "sqliteInt.h"
-/*
-** Return the number of faults (both hard and benign faults) that have
-** occurred since the injector was last configured.
-*/
-int sqlite3FaultFailures(int id){
- assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
- return memfault.nFail;
-}
+#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
-** Return the number of benign faults that have occurred since the
-** injector was last configured.
+** If zero, malloc() failures are non-benign. If non-zero, benign.
*/
-int sqlite3FaultBenignFailures(int id){
- return memfault.nBenign;
-}
+static int memfault_is_benign = 0;
/*
-** Return the number of successes that will occur before the next failure.
-** If no failures are scheduled, return -1.
+** Return true if a malloc failures are currently considered to be
+** benign. A benign fault does not affect the operation of sqlite.
+** By constrast a non-benign fault causes sqlite to fail the current
+** operation and return SQLITE_NOMEM to the user.
*/
-int sqlite3FaultPending(int id){
- if( memfault.enable ){
- return memfault.iCountdown;
- }else{
- return -1;
- }
+int sqlite3FaultIsBenign(void){
+ return memfault_is_benign;
}
/*
-** After this routine causes subsequent faults to be either benign
-** or hard (not benign), according to the "enable" parameter.
+** After this routine causes subsequent malloc faults to be either
+** benign or hard (not benign), according to the "enable" parameter.
**
** Most faults are hard. In other words, most faults cause
** an error to be propagated back up to the application interface.
** a hash table resize is a benign fault.
*/
void sqlite3FaultBeginBenign(int id){
- if( id<0 ){
- for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
- memfault.benign++;
- }
- }else{
- assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
- memfault.benign++;
- }
+ memfault_is_benign++;
}
void sqlite3FaultEndBenign(int id){
- if( id<0 ){
- for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
- assert( memfault.benign>0 );
- memfault.benign--;
- }
- }else{
- assert( memfault.benign>0 );
- memfault.benign--;
- }
+ memfault_is_benign--;
}
-int sqlite3FaultsimInstall(int install){
- static struct sqlite3_mem_methods m = {
- faultsimMalloc, /* xMalloc */
- faultsimFree, /* xFree */
- faultsimRealloc, /* xRealloc */
- faultsimSize, /* xSize */
- faultsimRoundup, /* xRoundup */
- faultsimInit, /* xInit */
- faultsimShutdown, /* xShutdown */
- 0 /* pAppData */
- };
- int rc;
-
- assert(install==1 || install==0);
- assert(memfault.isInstalled==1 || memfault.isInstalled==0);
-
- if( install==memfault.isInstalled ){
- return SQLITE_ERROR;
- }
-
- rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
- assert(memfault.m.xMalloc);
- if( rc==SQLITE_OK ){
- rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
- }
-
- if( rc==SQLITE_OK ){
- memfault.isInstalled = 1;
- }
- return rc;
-}
+#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.453 2008/06/19 18:17:50 danielk1977 Exp $
+** $Id: main.c,v 1.454 2008/06/20 11:05:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
va_list ap;
va_start(ap, op);
switch( op ){
+#if 0
/*
** sqlite3_test_control(FAULT_CONFIG, fault_id, nDelay, nRepeat)
**
rc = sqlite3FaultsimInstall(isInstall);
break;
}
+#endif
/*
** Save the current state of the PRNG.
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.718 2008/06/19 18:17:50 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.719 2008/06/20 11:05:38 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#define SQLITE_FAULTINJECTOR_COUNT 1
/*
-** The interface to the fault injector subsystem. If the fault injector
-** mechanism is disabled at compile-time then set up macros so that no
-** unnecessary code is generated.
+** The interface to the code in fault.c used for identifying "benign"
+** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
+** is not defined.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
- void sqlite3FaultConfig(int,int,int);
- int sqlite3FaultFailures(int);
- int sqlite3FaultBenignFailures(int);
- int sqlite3FaultPending(int);
void sqlite3FaultBeginBenign(int);
void sqlite3FaultEndBenign(int);
- int sqlite3FaultStep(int);
- int sqlite3FaultsimInstall(int);
+ int sqlite3FaultIsBenign(void);
#else
-# define sqlite3FaultConfig(A,B,C)
-# define sqlite3FaultFailures(A) 0
-# define sqlite3FaultBenignFailures(A) 0
-# define sqlite3FaultPending(A) (-1)
-# define sqlite3FaultBeginBenign(A)
-# define sqlite3FaultEndBenign(A)
-# define sqlite3FaultStep(A) 0
-#endif
-
-
+ #define sqlite3FaultBeginBenign()
+ #define sqlite3FaultEndBenign()
+#endif
#define IN_INDEX_ROWID 1
#define IN_INDEX_EPH 2
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
-** $Id: test_malloc.c,v 1.26 2008/06/19 18:17:50 danielk1977 Exp $
+** $Id: test_malloc.c,v 1.27 2008/06/20 11:05:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <string.h>
#include <assert.h>
+/*
+** This structure is used to encapsulate the global state variables used
+** by malloc() fault simulation.
+*/
+static struct MemFault {
+ int iCountdown; /* Number of pending successes before a failure */
+ int nRepeat; /* Number of times to repeat the failure */
+ int nBenign; /* Number of benign failures seen since last config */
+ int nFail; /* Number of failures seen since last config */
+ u8 enable; /* True if enabled */
+ int isInstalled; /* True if the fault simulation layer is installed */
+ sqlite3_mem_methods m; /* 'Real' malloc implementation */
+} memfault;
+
+/*
+** This routine exists as a place to set a breakpoint that will
+** fire on any simulated malloc() failure.
+*/
+static void sqlite3Fault(void){
+ static int cnt = 0;
+ cnt++;
+}
+
+/*
+** Check to see if a fault should be simulated. Return true to simulate
+** the fault. Return false if the fault should not be simulated.
+*/
+static int faultsimStep(){
+ if( likely(!memfault.enable) ){
+ return 0;
+ }
+ if( memfault.iCountdown>0 ){
+ memfault.iCountdown--;
+ return 0;
+ }
+ sqlite3Fault();
+ memfault.nFail++;
+ if( sqlite3FaultIsBenign()>0 ){
+ memfault.nBenign++;
+ }
+ memfault.nRepeat--;
+ if( memfault.nRepeat<=0 ){
+ memfault.enable = 0;
+ }
+ return 1;
+}
+
+/*
+** A version of sqlite3_mem_methods.xMalloc() that includes fault simulation
+** logic.
+*/
+static void *faultsimMalloc(int n){
+ void *p = 0;
+ if( !faultsimStep() ){
+ p = memfault.m.xMalloc(n);
+ }
+ return p;
+}
+
+
+/*
+** A version of sqlite3_mem_methods.xRealloc() that includes fault simulation
+** logic.
+*/
+static void *faultsimRealloc(void *pOld, int n){
+ void *p = 0;
+ if( !faultsimStep() ){
+ p = memfault.m.xRealloc(pOld, n);
+ }
+ return p;
+}
+
+/*
+** The following method calls are passed directly through to the underlying
+** malloc system:
+**
+** xFree
+** xSize
+** xRoundup
+** xInit
+** xShutdown
+*/
+static void faultsimFree(void *p){
+ memfault.m.xFree(p);
+}
+static int faultsimSize(void *p){
+ return memfault.m.xSize(p);
+}
+static int faultsimRoundup(int n){
+ return memfault.m.xRoundup(n);
+}
+static int faultsimInit(void *p){
+ return memfault.m.xInit(memfault.m.pAppData);
+}
+static void faultsimShutdown(void *p){
+ memfault.m.xShutdown(memfault.m.pAppData);
+}
+
+/*
+** This routine configures the malloc failure simulation. After
+** calling this routine, the next nDelay mallocs will succeed, followed
+** by a block of nRepeat failures, after which malloc() calls will begin
+** to succeed again.
+*/
+static void faultsimConfig(int nDelay, int nRepeat){
+ memfault.iCountdown = nDelay;
+ memfault.nRepeat = nRepeat;
+ memfault.nBenign = 0;
+ memfault.nFail = 0;
+ memfault.enable = nDelay>=0;
+}
+
+/*
+** Return the number of faults (both hard and benign faults) that have
+** occurred since the injector was last configured.
+*/
+static int faultsimFailures(void){
+ return memfault.nFail;
+}
+
+/*
+** Return the number of benign faults that have occurred since the
+** injector was last configured.
+*/
+static int faultsimBenignFailures(void){
+ return memfault.nBenign;
+}
+
+/*
+** Return the number of successes that will occur before the next failure.
+** If no failures are scheduled, return -1.
+*/
+static int faultsimPending(void){
+ if( memfault.enable ){
+ return memfault.iCountdown;
+ }else{
+ return -1;
+ }
+}
+
+/*
+** Add or remove the fault-simulation layer using sqlite3_config(). If
+** the argument is non-zero, the
+*/
+static int faultsimInstall(int install){
+ static struct sqlite3_mem_methods m = {
+ faultsimMalloc, /* xMalloc */
+ faultsimFree, /* xFree */
+ faultsimRealloc, /* xRealloc */
+ faultsimSize, /* xSize */
+ faultsimRoundup, /* xRoundup */
+ faultsimInit, /* xInit */
+ faultsimShutdown, /* xShutdown */
+ 0 /* pAppData */
+ };
+ int rc;
+
+ install = (install ? 1 : 0);
+ assert(memfault.isInstalled==1 || memfault.isInstalled==0);
+
+ if( install==memfault.isInstalled ){
+ return SQLITE_ERROR;
+ }
+
+ rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
+ assert(memfault.m.xMalloc);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
+ }
+
+ if( rc==SQLITE_OK ){
+ memfault.isInstalled = 1;
+ }
+ return rc;
+}
+
+#ifdef SQLITE_TEST
+
+/*
+** This function is implemented in test1.c. Returns a pointer to a static
+** buffer containing the symbolic SQLite error code that corresponds to
+** the least-significant 8-bits of the integer passed as an argument.
+** For example:
+**
+** sqlite3TestErrorName(1) -> "SQLITE_ERROR"
+*/
const char *sqlite3TestErrorName(int);
/*
return TCL_OK;
}
-
/*
** Usage: sqlite3_free PRIOR
**
}
}
- sqlite3_test_control(-12345); /* Just to stress the test_control interface */
- nBenign = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES,
- SQLITE_FAULTINJECTOR_MALLOC);
- nFail = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_FAILURES,
- SQLITE_FAULTINJECTOR_MALLOC);
- sqlite3_test_control(SQLITE_TESTCTRL_FAULT_CONFIG,
- SQLITE_FAULTINJECTOR_MALLOC, iFail, nRepeat);
+ nBenign = faultsimBenignFailures();
+ nFail = faultsimFailures();
+ faultsimConfig(iFail, nRepeat);
+
if( pBenignCnt ){
Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(nBenign), 0);
}
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
- nPending = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_PENDING,
- SQLITE_FAULTINJECTOR_MALLOC);
+ nPending = faultsimPending();
Tcl_SetObjResult(interp, Tcl_NewIntObj(nPending));
return TCL_OK;
}
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
return TCL_ERROR;
}
- rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, isInstall);
+ rc = faultsimInstall(isInstall);
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
return TCL_OK;
}
}
return TCL_OK;
}
+#endif