mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Move the malloc() failure simulation out of malloc.c and into a separate sqlite3_mem_methods interface. Still some related changes to come. (CVS 5250)
FossilOrigin-Name: d22cd2a59f472f4eaf80aa9f55fbff2514ca428d
This commit is contained in:
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
|||||||
C Documentation\sand\stest-script\supdates.\s(CVS\s5249)
|
C Move\sthe\smalloc()\sfailure\ssimulation\sout\sof\smalloc.c\sand\sinto\sa\sseparate\ssqlite3_mem_methods\sinterface.\sStill\ssome\srelated\schanges\sto\scome.\s(CVS\s5250)
|
||||||
D 2008-06-19T17:54:33
|
D 2008-06-19T18:17:50
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in ff6f90048555a0088f6a4b7406bed5e55a7c4eff
|
F Makefile.in ff6f90048555a0088f6a4b7406bed5e55a7c4eff
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -105,7 +105,7 @@ F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
|
|||||||
F src/date.c e841168e5520bbbb2a1cbcdce7531d8b23017b4d
|
F src/date.c e841168e5520bbbb2a1cbcdce7531d8b23017b4d
|
||||||
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
||||||
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
||||||
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
F src/fault.c 34d0f93490a659561a5a41bccb40cc1ef918d265
|
||||||
F src/func.c 1e7d9569570134ac0771a00382d9d4b41c4aa052
|
F src/func.c 1e7d9569570134ac0771a00382d9d4b41c4aa052
|
||||||
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
|
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
|
||||||
F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35
|
F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35
|
||||||
@ -115,8 +115,8 @@ F src/insert.c c2ead6c36566de8e3f130e7ab1431723a269d5d7
|
|||||||
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e
|
||||||
F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df
|
F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df
|
||||||
F src/loadext.c 40024a0f476c1279494876b9a002001b29e5d3e3
|
F src/loadext.c 40024a0f476c1279494876b9a002001b29e5d3e3
|
||||||
F src/main.c d75dad89c689c92cfb20d45f3ef31baca08eb896
|
F src/main.c ae01b4e90c6a323b689dea1e0af4bf98dc484c7f
|
||||||
F src/malloc.c 33b8a20684e65ce13f94e5b14fb0e6cdc335c5d1
|
F src/malloc.c 66c0b17a6611547f630b6ea67e14e575b9431507
|
||||||
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a
|
||||||
F src/mem1.c 159f10e280f2d9aea597cf938851e61652dd5c3d
|
F src/mem1.c 159f10e280f2d9aea597cf938851e61652dd5c3d
|
||||||
F src/mem2.c 23f9538f35fbcd5665afe7056a56be0c7ed65aa7
|
F src/mem2.c 23f9538f35fbcd5665afe7056a56be0c7ed65aa7
|
||||||
@ -143,9 +143,9 @@ F src/printf.c 8b063da9dcde26b7c500a01444b718d86f21bc6e
|
|||||||
F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a
|
F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a
|
||||||
F src/select.c 669687459e7d0193c89de06c5dbed55b4a41191c
|
F src/select.c 669687459e7d0193c89de06c5dbed55b4a41191c
|
||||||
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
|
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
|
||||||
F src/sqlite.h.in 379c716552d98527db1b1acc38d9d2164bba7956
|
F src/sqlite.h.in bf94fcce7c2da5e92d0037595238efbb4f5d0985
|
||||||
F src/sqlite3ext.h f162a72daef5ebf8b211fe8c0ec96e85d22fbf9b
|
F src/sqlite3ext.h f162a72daef5ebf8b211fe8c0ec96e85d22fbf9b
|
||||||
F src/sqliteInt.h 6dd55232e738a4dac23475cd4b0e444dff75c896
|
F src/sqliteInt.h 4d4c0432b5f4918beff36a075015b32244c420c3
|
||||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||||
F src/status.c 6cb10377992505bd69f1ca1d75c1240a65f25a58
|
F src/status.c 6cb10377992505bd69f1ca1d75c1240a65f25a58
|
||||||
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
||||||
@ -167,7 +167,7 @@ F src/test_devsym.c 6012cb8e3acf812513511025a4fa5d626e0ba19b
|
|||||||
F src/test_func.c f4aafa10f17d52c43a64b47717265802e6e552b3
|
F src/test_func.c f4aafa10f17d52c43a64b47717265802e6e552b3
|
||||||
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
|
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
|
||||||
F src/test_loadext.c df8ab3a6481ddebbdf0d28ebac5d9e0790f7860f
|
F src/test_loadext.c df8ab3a6481ddebbdf0d28ebac5d9e0790f7860f
|
||||||
F src/test_malloc.c dc6d256544b1be96312367b24b93a778de8afdfe
|
F src/test_malloc.c 8c8c0b5cad66b1cb5b8ccca6efec1739572a5978
|
||||||
F src/test_md5.c 28209a4e2068711b5443c33104fe41f21d160071
|
F src/test_md5.c 28209a4e2068711b5443c33104fe41f21d160071
|
||||||
F src/test_mutex.c 8cfe5c56d5583e07c25c50f59c42ca0104dd24bb
|
F src/test_mutex.c 8cfe5c56d5583e07c25c50f59c42ca0104dd24bb
|
||||||
F src/test_onefile.c 1f87d4a21cbfb24a7c35e4333fa0bd34d641f68d
|
F src/test_onefile.c 1f87d4a21cbfb24a7c35e4333fa0bd34d641f68d
|
||||||
@ -386,8 +386,8 @@ F test/lock2.test 018b846f6f3b3b695fad07e317b7988442b556f4
|
|||||||
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
||||||
F test/lock4.test 09d97d52cae18fadfe631552af9880dac6b3ae90
|
F test/lock4.test 09d97d52cae18fadfe631552af9880dac6b3ae90
|
||||||
F test/main.test 82c222989e02ea09abd58d453828ffd71806b6bf
|
F test/main.test 82c222989e02ea09abd58d453828ffd71806b6bf
|
||||||
F test/malloc.test fa208f99ed283b131ace2903f052375ab480de1a
|
F test/malloc.test ca6d4ebb9886ec1bdb78953ca0f53cf2e0846761
|
||||||
F test/malloc2.test 6f2abc0617a7df210381272681d598488a3bf943
|
F test/malloc2.test c847c457d37cf37ff9ff989fa6bd1475f714e485
|
||||||
F test/malloc3.test 094f8195fe8e409bd4da0f1d769f7745faec62c8
|
F test/malloc3.test 094f8195fe8e409bd4da0f1d769f7745faec62c8
|
||||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||||
F test/malloc5.test 1a68e56e513eab54d8c4cd1b769ff1d14e3f99f4
|
F test/malloc5.test 1a68e56e513eab54d8c4cd1b769ff1d14e3f99f4
|
||||||
@ -403,7 +403,7 @@ F test/mallocD.test f78c295e8e18ea3029e65ca08278690e00c22100
|
|||||||
F test/mallocE.test db1ed69d7eded1b080952e2a7c37f364ad241b08
|
F test/mallocE.test db1ed69d7eded1b080952e2a7c37f364ad241b08
|
||||||
F test/mallocF.test 2d5c590ebc2fc7f0dcebdf5aa8498b9aed69107e
|
F test/mallocF.test 2d5c590ebc2fc7f0dcebdf5aa8498b9aed69107e
|
||||||
F test/mallocG.test b295dc03b6d8d705ce425ff4d1ce6bbeb1c5ab33
|
F test/mallocG.test b295dc03b6d8d705ce425ff4d1ce6bbeb1c5ab33
|
||||||
F test/malloc_common.tcl fd7040bbb0bbbe84187c7f80049fdf6b2a4d699b
|
F test/malloc_common.tcl c3b251237a7a1578c49c4f342fa764c4c8fa613c
|
||||||
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
|
||||||
@ -600,7 +600,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 7d38da3eea9ce93f32e90fce0af5101e2cf12462
|
P 68d4f7954108f5bf586c4706c8664d8333fb2230
|
||||||
R 267d5dcbcec5655f8a7bf7ef07b9ba94
|
R 97546362f278f80be16b4e945792af6f
|
||||||
U drh
|
U danielk1977
|
||||||
Z 9d5c19f9eec6311440a093ba49ae5844
|
Z 7b2a0d71c4e09cb60bf9f1b81e5fb2c6
|
||||||
|
@ -1 +1 @@
|
|||||||
68d4f7954108f5bf586c4706c8664d8333fb2230
|
d22cd2a59f472f4eaf80aa9f55fbff2514ca428d
|
189
src/fault.c
189
src/fault.c
@ -26,41 +26,117 @@
|
|||||||
** under the motto "fly what you test and test what you fly" may
|
** under the motto "fly what you test and test what you fly" may
|
||||||
** choose to leave the fault injector enabled even in production.
|
** choose to leave the fault injector enabled even in production.
|
||||||
**
|
**
|
||||||
** $Id: fault.c,v 1.6 2008/05/15 19:43:53 drh Exp $
|
** $Id: fault.c,v 1.7 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** There can be various kinds of faults. For example, there can be
|
** There can be various kinds of faults. For example, there can be
|
||||||
** a memory allocation failure. Or an I/O failure. For each different
|
** a memory allocation failure. Or an I/O failure. For each different
|
||||||
** fault type, there is a separate FaultInjector structure to keep track
|
** fault type, there is a separate FaultInjector structure to keep track
|
||||||
** of the status of that fault.
|
** of the status of that fault.
|
||||||
*/
|
*/
|
||||||
static struct FaultInjector {
|
static struct MemFault {
|
||||||
int iCountdown; /* Number of pending successes before we hit a failure */
|
int iCountdown; /* Number of pending successes before we hit a failure */
|
||||||
int nRepeat; /* Number of times to repeat the failure */
|
int nRepeat; /* Number of times to repeat the failure */
|
||||||
int nBenign; /* Number of benign failures seen since last config */
|
int nBenign; /* Number of benign failures seen since last config */
|
||||||
int nFail; /* Number of failures seen since last config */
|
int nFail; /* Number of failures seen since last config */
|
||||||
u8 enable; /* True if enabled */
|
u8 enable; /* True if enabled */
|
||||||
i16 benign; /* Positive if next failure will be benign */
|
i16 benign; /* Positive if next failure will be benign */
|
||||||
} aFault[SQLITE_FAULTINJECTOR_COUNT];
|
|
||||||
|
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
|
** This routine configures and enables a fault injector. After
|
||||||
** calling this routine, aFaultStep() will return false (zero)
|
** calling this routine, a FaultStep() will return false (zero)
|
||||||
** nDelay times, then it will return true nRepeat times,
|
** nDelay times, then it will return true nRepeat times,
|
||||||
** then it will again begin returning false.
|
** then it will again begin returning false.
|
||||||
*/
|
*/
|
||||||
void sqlite3FaultConfig(int id, int nDelay, int nRepeat){
|
void sqlite3FaultConfig(int id, int nDelay, int nRepeat){
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
memfault.iCountdown = nDelay;
|
||||||
aFault[id].iCountdown = nDelay;
|
memfault.nRepeat = nRepeat;
|
||||||
aFault[id].nRepeat = nRepeat;
|
memfault.nBenign = 0;
|
||||||
aFault[id].nBenign = 0;
|
memfault.nFail = 0;
|
||||||
aFault[id].nFail = 0;
|
memfault.enable = nDelay>=0;
|
||||||
aFault[id].enable = nDelay>=0;
|
memfault.benign = 0;
|
||||||
aFault[id].benign = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -69,7 +145,7 @@ void sqlite3FaultConfig(int id, int nDelay, int nRepeat){
|
|||||||
*/
|
*/
|
||||||
int sqlite3FaultFailures(int id){
|
int sqlite3FaultFailures(int id){
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
||||||
return aFault[id].nFail;
|
return memfault.nFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -77,8 +153,7 @@ int sqlite3FaultFailures(int id){
|
|||||||
** injector was last configured.
|
** injector was last configured.
|
||||||
*/
|
*/
|
||||||
int sqlite3FaultBenignFailures(int id){
|
int sqlite3FaultBenignFailures(int id){
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
return memfault.nBenign;
|
||||||
return aFault[id].nBenign;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -86,9 +161,8 @@ int sqlite3FaultBenignFailures(int id){
|
|||||||
** If no failures are scheduled, return -1.
|
** If no failures are scheduled, return -1.
|
||||||
*/
|
*/
|
||||||
int sqlite3FaultPending(int id){
|
int sqlite3FaultPending(int id){
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
if( memfault.enable ){
|
||||||
if( aFault[id].enable ){
|
return memfault.iCountdown;
|
||||||
return aFault[id].iCountdown;
|
|
||||||
}else{
|
}else{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -109,59 +183,54 @@ int sqlite3FaultPending(int id){
|
|||||||
void sqlite3FaultBeginBenign(int id){
|
void sqlite3FaultBeginBenign(int id){
|
||||||
if( id<0 ){
|
if( id<0 ){
|
||||||
for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
|
for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
|
||||||
aFault[id].benign++;
|
memfault.benign++;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
||||||
aFault[id].benign++;
|
memfault.benign++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void sqlite3FaultEndBenign(int id){
|
void sqlite3FaultEndBenign(int id){
|
||||||
if( id<0 ){
|
if( id<0 ){
|
||||||
for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
|
for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
|
||||||
assert( aFault[id].benign>0 );
|
assert( memfault.benign>0 );
|
||||||
aFault[id].benign--;
|
memfault.benign--;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
assert( memfault.benign>0 );
|
||||||
assert( aFault[id].benign>0 );
|
memfault.benign--;
|
||||||
aFault[id].benign--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int sqlite3FaultsimInstall(int install){
|
||||||
** This routine exists as a place to set a breakpoint that will
|
static struct sqlite3_mem_methods m = {
|
||||||
** fire on any simulated fault.
|
faultsimMalloc, /* xMalloc */
|
||||||
*/
|
faultsimFree, /* xFree */
|
||||||
static void sqlite3Fault(void){
|
faultsimRealloc, /* xRealloc */
|
||||||
static int cnt = 0;
|
faultsimSize, /* xSize */
|
||||||
cnt++;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Check to see if a fault should be simulated. Return true to simulate
|
|
||||||
** the fault. Return false if the fault should not be simulated.
|
|
||||||
*/
|
|
||||||
int sqlite3FaultStep(int id){
|
|
||||||
assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
|
|
||||||
if( likely(!aFault[id].enable) ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if( aFault[id].iCountdown>0 ){
|
|
||||||
aFault[id].iCountdown--;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
sqlite3Fault();
|
|
||||||
aFault[id].nFail++;
|
|
||||||
if( aFault[id].benign>0 ){
|
|
||||||
aFault[id].nBenign++;
|
|
||||||
}
|
|
||||||
aFault[id].nRepeat--;
|
|
||||||
if( aFault[id].nRepeat<=0 ){
|
|
||||||
aFault[id].enable = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SQLITE_OMIT_BUILTIN_TEST */
|
|
||||||
|
14
src/main.c
14
src/main.c
@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.452 2008/06/19 01:03:18 drh Exp $
|
** $Id: main.c,v 1.453 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1816,6 +1816,18 @@ int sqlite3_test_control(int op, ...){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** sqlite3_test_control(FAULT_INSTALL, isInstall)
|
||||||
|
**
|
||||||
|
** If the argument is non-zero, install the fault-simulation malloc layer
|
||||||
|
** as a wrapper around the currently installed implementation.
|
||||||
|
*/
|
||||||
|
case SQLITE_TESTCTRL_FAULT_INSTALL: {
|
||||||
|
int isInstall = va_arg(ap, int);
|
||||||
|
rc = sqlite3FaultsimInstall(isInstall);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Save the current state of the PRNG.
|
** Save the current state of the PRNG.
|
||||||
*/
|
*/
|
||||||
|
28
src/malloc.c
28
src/malloc.c
@ -12,7 +12,7 @@
|
|||||||
**
|
**
|
||||||
** Memory allocation functions used throughout sqlite.
|
** Memory allocation functions used throughout sqlite.
|
||||||
**
|
**
|
||||||
** $Id: malloc.c,v 1.21 2008/06/19 00:16:08 drh Exp $
|
** $Id: malloc.c,v 1.22 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -213,14 +213,10 @@ static int mallocWithAlarm(int n, void **pp){
|
|||||||
sqlite3MallocAlarm(nFull);
|
sqlite3MallocAlarm(nFull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
p = sqlite3Config.m.xMalloc(nFull);
|
||||||
p = 0;
|
if( p==0 && mem0.alarmCallback ){
|
||||||
}else{
|
sqlite3MallocAlarm(nFull);
|
||||||
p = sqlite3Config.m.xMalloc(nFull);
|
p = sqlite3Config.m.xMalloc(nFull);
|
||||||
if( p==0 ){
|
|
||||||
sqlite3MallocAlarm(nFull);
|
|
||||||
p = malloc(nFull);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( p ) sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
|
if( p ) sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
|
||||||
*pp = p;
|
*pp = p;
|
||||||
@ -279,9 +275,6 @@ static int scratchAllocOut = 0;
|
|||||||
void *sqlite3ScratchMalloc(int n){
|
void *sqlite3ScratchMalloc(int n){
|
||||||
void *p;
|
void *p;
|
||||||
assert( n>0 );
|
assert( n>0 );
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
|
#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
|
||||||
/* Verify that no more than one scratch allocation per thread
|
/* Verify that no more than one scratch allocation per thread
|
||||||
@ -377,9 +370,6 @@ void *sqlite3PageMalloc(int n){
|
|||||||
assert( n>0 );
|
assert( n>0 );
|
||||||
assert( (n & (n-1))==0 );
|
assert( (n & (n-1))==0 );
|
||||||
assert( n>=512 && n<=32768 );
|
assert( n>=512 && n<=32768 );
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( sqlite3Config.szPage<n ){
|
if( sqlite3Config.szPage<n ){
|
||||||
goto page_overflow;
|
goto page_overflow;
|
||||||
@ -487,14 +477,10 @@ void *sqlite3Realloc(void *pOld, int nBytes){
|
|||||||
mem0.alarmThreshold ){
|
mem0.alarmThreshold ){
|
||||||
sqlite3MallocAlarm(nNew-nOld);
|
sqlite3MallocAlarm(nNew-nOld);
|
||||||
}
|
}
|
||||||
if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
|
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
|
||||||
pNew = 0;
|
if( pNew==0 && mem0.alarmCallback ){
|
||||||
}else{
|
sqlite3MallocAlarm(nBytes);
|
||||||
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
|
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
|
||||||
if( pNew==0 ){
|
|
||||||
sqlite3MallocAlarm(nBytes);
|
|
||||||
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( pNew ){
|
if( pNew ){
|
||||||
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
|
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
** the version number) and changes its name to "sqlite3.h" as
|
** the version number) and changes its name to "sqlite3.h" as
|
||||||
** part of the build process.
|
** part of the build process.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqlite.h.in,v 1.340 2008/06/19 17:54:33 drh Exp $
|
** @(#) $Id: sqlite.h.in,v 1.341 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE3_H_
|
#ifndef _SQLITE3_H_
|
||||||
#define _SQLITE3_H_
|
#define _SQLITE3_H_
|
||||||
@ -6060,6 +6060,7 @@ int sqlite3_test_control(int op, ...);
|
|||||||
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
|
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
|
||||||
#define SQLITE_TESTCTRL_PRNG_RESET 7
|
#define SQLITE_TESTCTRL_PRNG_RESET 7
|
||||||
#define SQLITE_TESTCTRL_BITVEC_TEST 8
|
#define SQLITE_TESTCTRL_BITVEC_TEST 8
|
||||||
|
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: SQLite Runtime Status {F17200}
|
** CAPI3REF: SQLite Runtime Status {F17200}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.717 2008/06/19 01:03:18 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.718 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@ -2215,6 +2215,7 @@ CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
|
|||||||
void sqlite3FaultBeginBenign(int);
|
void sqlite3FaultBeginBenign(int);
|
||||||
void sqlite3FaultEndBenign(int);
|
void sqlite3FaultEndBenign(int);
|
||||||
int sqlite3FaultStep(int);
|
int sqlite3FaultStep(int);
|
||||||
|
int sqlite3FaultsimInstall(int);
|
||||||
#else
|
#else
|
||||||
# define sqlite3FaultConfig(A,B,C)
|
# define sqlite3FaultConfig(A,B,C)
|
||||||
# define sqlite3FaultFailures(A) 0
|
# define sqlite3FaultFailures(A) 0
|
||||||
|
@ -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.25 2008/06/19 00:16:08 drh Exp $
|
** $Id: test_malloc.c,v 1.26 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@ -21,6 +21,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
const char *sqlite3TestErrorName(int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Transform pointers to text and back again
|
** Transform pointers to text and back again
|
||||||
*/
|
*/
|
||||||
@ -780,6 +782,30 @@ static int test_status(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** install_malloc_faultsim BOOLEAN
|
||||||
|
*/
|
||||||
|
static int test_install_malloc_faultsim(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
int rc;
|
||||||
|
int isInstall;
|
||||||
|
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, isInstall);
|
||||||
|
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Register commands with the TCL interpreter.
|
** Register commands with the TCL interpreter.
|
||||||
*/
|
*/
|
||||||
@ -805,6 +831,8 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
|
|||||||
{ "sqlite3_config_scratch", test_config_scratch },
|
{ "sqlite3_config_scratch", test_config_scratch },
|
||||||
{ "sqlite3_config_pagecache", test_config_pagecache },
|
{ "sqlite3_config_pagecache", test_config_pagecache },
|
||||||
{ "sqlite3_status", test_status },
|
{ "sqlite3_status", test_status },
|
||||||
|
|
||||||
|
{ "install_malloc_faultsim", test_install_malloc_faultsim },
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||||
|
@ -16,11 +16,12 @@
|
|||||||
# to see what happens in the library if a malloc were to really fail
|
# to see what happens in the library if a malloc were to really fail
|
||||||
# due to an out-of-memory situation.
|
# due to an out-of-memory situation.
|
||||||
#
|
#
|
||||||
# $Id: malloc.test,v 1.61 2008/04/17 14:16:42 drh Exp $
|
# $Id: malloc.test,v 1.62 2008/06/19 18:17:50 danielk1977 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.
|
||||||
#
|
#
|
||||||
source $testdir/malloc_common.tcl
|
source $testdir/malloc_common.tcl
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# Recovery from malloc() failures is automatic. But we keep these
|
# Recovery from malloc() failures is automatic. But we keep these
|
||||||
# tests around because you can never have too many test cases.
|
# tests around because you can never have too many test cases.
|
||||||
#
|
#
|
||||||
# $Id: malloc2.test,v 1.12 2008/02/18 22:24:58 drh Exp $
|
# $Id: malloc2.test,v 1.13 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -37,7 +37,7 @@ proc do_malloc2_test {tn args} {
|
|||||||
set sum [allcksum db]
|
set sum [allcksum db]
|
||||||
save_prng_state
|
save_prng_state
|
||||||
|
|
||||||
for {set ::n 784} {true} {incr ::n} {
|
for {set ::n 1} {true} {incr ::n} {
|
||||||
|
|
||||||
# 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.
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# This file contains common code used by many different malloc tests
|
# This file contains common code used by many different malloc tests
|
||||||
# within the test suite.
|
# within the test suite.
|
||||||
#
|
#
|
||||||
# $Id: malloc_common.tcl,v 1.16 2008/03/21 16:45:48 drh Exp $
|
# $Id: malloc_common.tcl,v 1.17 2008/06/19 18:17:50 danielk1977 Exp $
|
||||||
|
|
||||||
# If we did not compile with malloc testing enabled, then do nothing.
|
# If we did not compile with malloc testing enabled, then do nothing.
|
||||||
#
|
#
|
||||||
@ -23,6 +23,11 @@ ifcapable builtin_test {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch {db close}
|
||||||
|
sqlite3_shutdown
|
||||||
|
catch {install_malloc_faultsim 1} msg
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
# Usage: do_malloc_test <test number> <options...>
|
# Usage: do_malloc_test <test number> <options...>
|
||||||
#
|
#
|
||||||
# The first argument, <test number>, is an integer used to name the
|
# The first argument, <test number>, is an integer used to name the
|
||||||
|
Reference in New Issue
Block a user