1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add the --oom option to fuzzershell.

FossilOrigin-Name: 14a9e4a377bf2974f5db148c8f86e2c5ffdfa28d
This commit is contained in:
drh
2015-04-24 23:45:23 +00:00
parent 61a0d6bc55
commit 048810b63b
3 changed files with 154 additions and 63 deletions

View File

@ -1,5 +1,5 @@
C Fix\sfuzzershell\sso\sthat\sit\sworks\swith\sSQLITE_OMIT_TRACE.
D 2015-04-24T18:31:12.676
C Add\sthe\s--oom\soption\sto\sfuzzershell.
D 2015-04-24T23:45:23.568
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 31b38b9da2e4b36f54a013bd71a5c3f6e45ca78f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -1205,7 +1205,7 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/fuzzershell.c a13c48cb83bbea8966442d777e14595b87023701
F tool/fuzzershell.c 96fb9b18a3e77777290b59bee9a2759dab3a8ef9
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
@ -1253,7 +1253,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 4dda916a572bcb54c8cf3b81d965328632a722eb
R fafcb3fcae40447c0604a45203b7a18d
P dc88fe7e641c52d27fba8c753cee590db87388c5
R b6b6b08ed6fc824093828aadd4063979
U drh
Z 443a2106b8aed7f08a3ed861aaf1e388
Z 5f3b959ee8a94e01f097246d319ba4ca

View File

@ -1 +1 @@
dc88fe7e641c52d27fba8c753cee590db87388c5
14a9e4a377bf2974f5db148c8f86e2c5ffdfa28d

View File

@ -72,10 +72,50 @@
*/
struct GlobalVars {
const char *zArgv0; /* Name of program */
sqlite3_mem_methods sOrigMem; /* Original memory methods */
sqlite3_mem_methods sOomMem; /* Memory methods with OOM simulator */
int iOomCntdown; /* Memory fails on 1 to 0 transition */
int nOomFault; /* Increments for each OOM fault */
int bOomOnce; /* Fail just once if true */
int bOomEnable; /* True to enable OOM simulation */
int nOomBrkpt; /* Number of calls to oomFault() */
} g;
/*
** This routine is called when a simulated OOM occurs. It exists as a
** convenient place to set a debugger breakpoint.
*/
static void oomFault(void){
g.nOomBrkpt++;
}
/* Versions of malloc() and realloc() that simulate OOM conditions */
static void *oomMalloc(int nByte){
if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){
g.iOomCntdown--;
if( g.iOomCntdown==0 ){
if( g.nOomFault==0 ) oomFault();
g.nOomFault++;
if( !g.bOomOnce ) g.iOomCntdown = 1;
return 0;
}
}
return g.sOrigMem.xMalloc(nByte);
}
static void *oomRealloc(void *pOld, int nByte){
if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){
g.iOomCntdown--;
if( g.iOomCntdown==0 ){
if( g.nOomFault==0 ) oomFault();
g.nOomFault++;
if( !g.bOomOnce ) g.iOomCntdown = 1;
return 0;
}
}
return g.sOrigMem.xRealloc(pOld, nByte);
}
/*
** Print an error message and abort in such a way to indicate to the
** fuzzer that this counts as a crash.
@ -259,6 +299,7 @@ static void showHelp(void){
" --help Show this help text\n"
" --initdb DBFILE Initialize the in-memory database using template DBFILE\n"
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
" --oom Run each test multiple times in a simulated OOM loop\n"
" --pagesize N Set the page size to N\n"
" --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
" -q Reduced output\n"
@ -376,8 +417,13 @@ int main(int argc, char **argv){
sqlite3_stmt *pStmt = 0; /* Statement to insert testcase into dataDb */
const char *zDataOut = 0; /* Write compacted data to this output file */
int nHeader = 0; /* Bytes of header comment text on input file */
int oomFlag = 0; /* --oom */
int oomCnt = 0; /* Counter for the OOM loop */
char zErrBuf[200]; /* Space for the error message */
const char *zFailCode; /* Value of the TEST_FAILURE environment var */
zFailCode = getenv("TEST_FAILURE");
g.zArgv0 = argv[0];
for(i=1; i<argc; i++){
const char *z = argv[i];
@ -431,6 +477,9 @@ int main(int argc, char **argv){
abendError("unknown --mode: %s", z);
}
}else
if( strcmp(z,"oom")==0 ){
oomFlag = 1;
}else
if( strcmp(z,"pagesize")==0 ){
if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
pageSize = integerValue(argv[++i]);
@ -480,6 +529,13 @@ int main(int argc, char **argv){
rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
if( rc ) abendError("heap configuration failed: %d\n", rc);
}
if( oomFlag ){
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &g.sOrigMem);
g.sOomMem = g.sOrigMem;
g.sOomMem.xMalloc = oomMalloc;
g.sOomMem.xRealloc = oomRealloc;
sqlite3_config(SQLITE_CONFIG_MALLOC, &g.sOomMem);
}
if( nLook>0 ){
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
if( szLook>0 ){
@ -557,6 +613,39 @@ int main(int argc, char **argv){
zIn[iNext] = cSaved;
continue;
}
zSql = &zIn[i];
if( verboseFlag ){
printf("INPUT (offset: %d, size: %d): [%s]\n",
i, (int)strlen(&zIn[i]), &zIn[i]);
}else if( multiTest && !quietFlag ){
int pct = oomFlag ? 100*iNext/nIn : ((10*iNext)/nIn)*10;
if( pct!=lastPct ){
if( lastPct<0 ) printf("fuzz test:");
printf(" %d%%", pct);
fflush(stdout);
lastPct = pct;
}
}
switch( iMode ){
case FZMODE_Glob:
zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
break;
case FZMODE_Printf:
zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
break;
case FZMODE_Strftime:
zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
break;
}
if( oomFlag ){
oomCnt = g.iOomCntdown = 1;
g.nOomFault = 0;
g.bOomOnce = 1;
if( verboseFlag ) printf("Once.%d\n", oomCnt);
}else{
oomCnt = 0;
}
do{
rc = sqlite3_open_v2(
"main.db", &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
@ -587,32 +676,45 @@ int main(int argc, char **argv){
if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
zSql = &zIn[i];
g.bOomEnable = 1;
if( verboseFlag ){
printf("INPUT (offset: %d, size: %d): [%s]\n",
i, (int)strlen(&zIn[i]), &zIn[i]);
}else if( multiTest && !quietFlag ){
int pct = 10*iNext/nIn;
if( pct!=lastPct ){
if( lastPct<0 ) printf("fuzz test:");
printf(" %d%%", pct*10);
fflush(stdout);
lastPct = pct;
}
}
switch( iMode ){
case FZMODE_Glob:
zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
break;
case FZMODE_Printf:
zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
break;
case FZMODE_Strftime:
zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
break;
}
zErrMsg = 0;
rc = sqlite3_exec(db, zSql, verboseFlag ? execCallback : execNoop, 0, &zErrMsg);
rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
if( zErrMsg ){
sqlite3_snprintf(sizeof(zErrBuf),zErrBuf,"%z", zErrMsg);
zErrMsg = 0;
}
}else {
rc = sqlite3_exec(db, zSql, execNoop, 0, 0);
}
g.bOomEnable = 0;
rc = sqlite3_close(db);
if( rc ){
abendError("sqlite3_close() failed with rc=%d", rc);
}
if( sqlite3_memory_used()>0 ){
abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
}
if( oomFlag ){
if( g.nOomFault==0 || oomCnt>2000 ){
if( g.bOomOnce ){
oomCnt = g.iOomCntdown = 1;
g.bOomOnce = 0;
}else{
oomCnt = 0;
}
}else{
g.iOomCntdown = ++oomCnt;
g.nOomFault = 0;
}
if( oomCnt ){
if( verboseFlag ){
printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt);
}
nTest++;
}
}
}while( oomCnt>0 );
if( zToFree ){
sqlite3_free(zToFree);
zToFree = 0;
@ -621,20 +723,10 @@ int main(int argc, char **argv){
if( verboseFlag ){
printf("RESULT-CODE: %d\n", rc);
if( zErrMsg ){
printf("ERROR-MSG: [%s]\n", zErrMsg);
printf("ERROR-MSG: [%s]\n", zErrBuf);
}
}
sqlite3_free(zErrMsg);
rc = sqlite3_close(db);
if( rc ){
abendError("sqlite3_close() failed with rc=%d", rc);
}
if( sqlite3_memory_used()>0 ){
abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
}
if( nTest==1 ){
/* Simulate an error if the TEST_FAILURE environment variable is "5" */
char *zFailCode = getenv("TEST_FAILURE");
if( zFailCode ){
if( zFailCode[0]=='5' && zFailCode[1]==0 ){
abendError("simulated failure");
@ -646,7 +738,6 @@ int main(int argc, char **argv){
}
}
}
}
if( !verboseFlag && multiTest && !quietFlag ) printf("\n");
if( nTest>1 && !quietFlag ){
printf("%d fuzz tests with no errors\nSQLite %s %s\n",