mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-21 09:00:59 +03:00
Merge all recent changes from trunk, and especially the new sqlite3FaultSim()
interface. FossilOrigin-Name: 43fcbd9116401f30781fdcbe55d1674d6b96311b
This commit is contained in:
13
src/global.c
13
src/global.c
@@ -174,15 +174,22 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
0, /* isMutexInit */
|
||||
0, /* isMallocInit */
|
||||
0, /* isPCacheInit */
|
||||
0, /* pInitMutex */
|
||||
0, /* nRefInitMutex */
|
||||
0, /* pInitMutex */
|
||||
0, /* xLog */
|
||||
0, /* pLogArg */
|
||||
0, /* bLocaltimeFault */
|
||||
#ifdef SQLITE_ENABLE_SQLLOG
|
||||
0, /* xSqllog */
|
||||
0 /* pSqllogArg */
|
||||
0, /* pSqllogArg */
|
||||
#endif
|
||||
#ifdef SQLITE_VDBE_COVERAGE
|
||||
0, /* xVdbeBranch */
|
||||
0, /* pVbeBranchArg */
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
||||
0, /* xTestCallback */
|
||||
#endif
|
||||
0 /* bLocaltimeFault */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
17
src/main.c
17
src/main.c
@@ -3124,6 +3124,23 @@ int sqlite3_test_control(int op, ...){
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_test_control(FAULT_INSTALL, xCallback)
|
||||
**
|
||||
** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called,
|
||||
** if xCallback is not NULL.
|
||||
**
|
||||
** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0)
|
||||
** is called immediately after installing the new callback and the return
|
||||
** value from sqlite3FaultSim(0) becomes the return from
|
||||
** sqlite3_test_control().
|
||||
*/
|
||||
case SQLITE_TESTCTRL_FAULT_INSTALL: {
|
||||
sqlite3Config.xTestCallback = va_arg(ap, int(*)(int));
|
||||
rc = sqlite3FaultSim(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
|
||||
**
|
||||
|
||||
@@ -13,17 +13,19 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
#if SQLITE_OS_WIN
|
||||
/*
|
||||
** Include the header file for the Windows VFS.
|
||||
*/
|
||||
#include "os_win.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The code in this file is only used if we are compiling multithreaded
|
||||
** on a win32 system.
|
||||
*/
|
||||
#ifdef SQLITE_MUTEX_W32
|
||||
|
||||
/*
|
||||
** Include the header file for the Windows VFS.
|
||||
*/
|
||||
#include "os_win.h"
|
||||
|
||||
/*
|
||||
** Each recursive mutex is an instance of the following structure.
|
||||
*/
|
||||
|
||||
@@ -2732,11 +2732,10 @@ struct Sqlite3Config {
|
||||
int isMutexInit; /* True after mutexes are initialized */
|
||||
int isMallocInit; /* True after malloc is initialized */
|
||||
int isPCacheInit; /* True after malloc is initialized */
|
||||
sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
|
||||
int nRefInitMutex; /* Number of users of pInitMutex */
|
||||
sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
|
||||
void (*xLog)(void*,int,const char*); /* Function for logging */
|
||||
void *pLogArg; /* First argument to xLog() */
|
||||
int bLocaltimeFault; /* True to fail localtime() calls */
|
||||
#ifdef SQLITE_ENABLE_SQLLOG
|
||||
void(*xSqllog)(void*,sqlite3*,const char*, int);
|
||||
void *pSqllogArg;
|
||||
@@ -2748,6 +2747,10 @@ struct Sqlite3Config {
|
||||
void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
|
||||
void *pVdbeBranchArg; /* 1st argument */
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
||||
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
|
||||
#endif
|
||||
int bLocaltimeFault; /* True to fail localtime() calls */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3049,6 +3052,12 @@ int sqlite3ParseUri(const char*,const char*,unsigned int*,
|
||||
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
|
||||
int sqlite3CodeOnce(Parse *);
|
||||
|
||||
#ifdef SQLITE_OMIT_BUILTIN_TEST
|
||||
# define sqlite3FaultSim(X) SQLITE_OK
|
||||
#else
|
||||
int sqlite3FaultSim(int);
|
||||
#endif
|
||||
|
||||
Bitvec *sqlite3BitvecCreate(u32);
|
||||
int sqlite3BitvecTest(Bitvec*, u32);
|
||||
int sqlite3BitvecSet(Bitvec*, u32);
|
||||
|
||||
88
src/test2.c
88
src/test2.c
@@ -568,7 +568,90 @@ static int testPendingByte(
|
||||
rc = sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, pbyte);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** The sqlite3FaultSim() callback:
|
||||
*/
|
||||
static Tcl_Interp *faultSimInterp = 0;
|
||||
static int faultSimScriptSize = 0;
|
||||
static char *faultSimScript;
|
||||
static int faultSimCallback(int x){
|
||||
char zInt[30];
|
||||
int i;
|
||||
int isNeg;
|
||||
int rc;
|
||||
if( x==0 ){
|
||||
memcpy(faultSimScript+faultSimScriptSize, "0", 2);
|
||||
}else{
|
||||
/* Convert x to text without using any sqlite3 routines */
|
||||
if( x<0 ){
|
||||
isNeg = 1;
|
||||
x = -x;
|
||||
}else{
|
||||
isNeg = 0;
|
||||
}
|
||||
zInt[sizeof(zInt)-1] = 0;
|
||||
for(i=sizeof(zInt)-2; i>0 && x>0; i--, x /= 10){
|
||||
zInt[i] = (x%10) + '0';
|
||||
}
|
||||
if( isNeg ) zInt[i--] = '-';
|
||||
memcpy(faultSimScript+faultSimScriptSize, zInt+i+1, sizeof(zInt)-i);
|
||||
}
|
||||
rc = Tcl_Eval(faultSimInterp, faultSimScript);
|
||||
if( rc ){
|
||||
fprintf(stderr, "fault simulator script failed: [%s]", faultSimScript);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
rc = atoi(Tcl_GetStringResult(faultSimInterp));
|
||||
}
|
||||
Tcl_ResetResult(faultSimInterp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_test_control_fault_install SCRIPT
|
||||
**
|
||||
** Arrange to invoke SCRIPT with the integer argument to sqlite3FaultSim()
|
||||
** appended, whenever sqlite3FaultSim() is called. Or, if SCRIPT is the
|
||||
** empty string, cancel the sqlite3FaultSim() callback.
|
||||
*/
|
||||
static int faultInstallCmd(
|
||||
void *NotUsed,
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int argc, /* Number of arguments */
|
||||
const char **argv /* Text of each argument */
|
||||
){
|
||||
const char *zScript;
|
||||
int nScript;
|
||||
int rc;
|
||||
if( argc!=1 && argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" SCRIPT\"", (void*)0);
|
||||
}
|
||||
zScript = argc==2 ? argv[1] : "";
|
||||
nScript = (int)strlen(zScript);
|
||||
if( faultSimScript ){
|
||||
free(faultSimScript);
|
||||
faultSimScript = 0;
|
||||
}
|
||||
if( nScript==0 ){
|
||||
rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, 0);
|
||||
}else{
|
||||
faultSimScript = malloc( nScript+100 );
|
||||
if( faultSimScript==0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", (void*)0);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
memcpy(faultSimScript, zScript, nScript);
|
||||
faultSimScript[nScript] = ' ';
|
||||
faultSimScriptSize = nScript+1;
|
||||
faultSimInterp = interp;
|
||||
rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, faultSimCallback);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3BitvecBuiltinTest SIZE PROGRAM
|
||||
@@ -638,7 +721,8 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
||||
{ "fake_big_file", (Tcl_CmdProc*)fake_big_file },
|
||||
#endif
|
||||
{ "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest },
|
||||
{ "sqlite3_test_control_pending_byte", (Tcl_CmdProc*)testPendingByte },
|
||||
{ "sqlite3_test_control_pending_byte", (Tcl_CmdProc*)testPendingByte },
|
||||
{ "sqlite3_test_control_fault_install", (Tcl_CmdProc*)faultInstallCmd },
|
||||
};
|
||||
int i;
|
||||
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
|
||||
|
||||
18
src/util.c
18
src/util.c
@@ -31,6 +31,24 @@ void sqlite3Coverage(int x){
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Give a callback to the test harness that can be used to simulate faults
|
||||
** in places where it is difficult or expensive to do so purely by means
|
||||
** of inputs.
|
||||
**
|
||||
** The intent of the integer argument is to let the fault simulator know
|
||||
** which of multiple sqlite3FaultSim() calls has been hit.
|
||||
**
|
||||
** Return whatever integer value the test callback returns, or return
|
||||
** SQLITE_OK if no test callback is installed.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
||||
int sqlite3FaultSim(int iTest){
|
||||
int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
|
||||
return xCallback ? xCallback(iTest) : SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
/*
|
||||
** Return true if the floating point value is Not a Number (NaN).
|
||||
|
||||
Reference in New Issue
Block a user