Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d22cd2a59f472f4eaf80aa9f55fbff25 |
User & Date: | danielk1977 2008-06-19 18:17:50.000 |
Context
2008-06-19
| ||
18:39 | Unset global TCL variables in the func.test script prior to use to avoid conflicts from other scripts. (CVS 5251) (check-in: 9b04e10f6c user: drh tags: trunk) | |
18:17 | 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) (check-in: d22cd2a59f user: danielk1977 tags: trunk) | |
17:54 | Documentation and test-script updates. (CVS 5249) (check-in: 68d4f79541 user: drh tags: trunk) | |
Changes
Changes to src/fault.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | ** 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. ** | | < < | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < | | | | | | | < | < | | | | | | < | | < < < < | | > > > > > | > > | | < < < < < < | | | | < | | | > | | | | | | | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | ** 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. */ 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; } /* ** 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; } /* ** Return the number of benign faults that have occurred since the ** injector was last configured. */ int sqlite3FaultBenignFailures(int id){ return memfault.nBenign; } /* ** Return the number of successes that will occur before the next failure. ** If no failures are scheduled, return -1. */ int sqlite3FaultPending(int id){ if( memfault.enable ){ return memfault.iCountdown; }else{ return -1; } } /* ** After this routine causes subsequent 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. ** However, sometimes a fault is easily recoverable. For example, ** if a malloc fails while resizing a hash table, this is completely ** recoverable simply by not carrying out the resize. The hash table ** will continue to function normally. So a malloc failure during ** 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++; } } 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--; } } 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; } |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** 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 $ */ #include "sqliteInt.h" #include <ctype.h> #ifdef SQLITE_ENABLE_FTS3 # include "fts3.h" #endif |
︙ | ︙ | |||
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | ** If no failures are scheduled, return -1. */ case SQLITE_TESTCTRL_FAULT_PENDING: { int id = va_arg(ap, int); rc = sqlite3FaultPending(id); break; } /* ** Save the current state of the PRNG. */ case SQLITE_TESTCTRL_PRNG_SAVE: { sqlite3PrngSaveState(); break; | > > > > > > > > > > > > | 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 | ** If no failures are scheduled, return -1. */ case SQLITE_TESTCTRL_FAULT_PENDING: { int id = va_arg(ap, int); rc = sqlite3FaultPending(id); 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. */ case SQLITE_TESTCTRL_PRNG_SAVE: { sqlite3PrngSaveState(); break; |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** ** $Id: malloc.c,v 1.22 2008/06/19 18:17:50 danielk1977 Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the |
︙ | ︙ | |||
209 210 211 212 213 214 215 | sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmCallback!=0 ){ int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed+nFull >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nFull); } } | < < < | | | | < | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmCallback!=0 ){ int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed+nFull >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nFull); } } p = sqlite3Config.m.xMalloc(nFull); if( p==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nFull); p = sqlite3Config.m.xMalloc(nFull); } if( p ) sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull); *pp = p; return nFull; } /* |
︙ | ︙ | |||
275 276 277 278 279 280 281 | ** routine is intended to get memory to old large transient data ** structures that would not normally fit on the stack of an ** embedded processor. */ void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); | < < < | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | ** routine is intended to get memory to old large transient data ** structures that would not normally fit on the stack of an ** embedded processor. */ void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) /* Verify that no more than one scratch allocation per thread ** is outstanding at one time. (This is only checked in the ** single-threaded case since checking in the multi-threaded case ** would be much more complicated.) */ assert( scratchAllocOut==0 ); |
︙ | ︙ | |||
373 374 375 376 377 378 379 | ** consumed. Otherwise, failover to sqlite3Malloc(). */ void *sqlite3PageMalloc(int n){ void *p; assert( n>0 ); assert( (n & (n-1))==0 ); assert( n>=512 && n<=32768 ); | < < < | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | ** consumed. Otherwise, failover to sqlite3Malloc(). */ void *sqlite3PageMalloc(int n){ void *p; assert( n>0 ); assert( (n & (n-1))==0 ); assert( n>=512 && n<=32768 ); if( sqlite3Config.szPage<n ){ goto page_overflow; }else{ sqlite3_mutex_enter(mem0.mutex); if( mem0.nPageFree==0 ){ sqlite3_mutex_leave(mem0.mutex); |
︙ | ︙ | |||
483 484 485 486 487 488 489 | if( nOld==nNew ){ pNew = pOld; }else{ if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nNew-nOld); } | < < < | | | | < | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 | if( nOld==nNew ){ pNew = pOld; }else{ if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nNew-nOld); } pNew = sqlite3Config.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nBytes); pNew = sqlite3Config.m.xRealloc(pOld, nNew); } if( pNew ){ sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); } } sqlite3_mutex_leave(mem0.mutex); }else{ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** ** @(#) $Id: sqlite.h.in,v 1.341 2008/06/19 18:17:50 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 | #define SQLITE_TESTCTRL_FAULT_FAILURES 2 #define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES 3 #define SQLITE_TESTCTRL_FAULT_PENDING 4 #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 /* ** CAPI3REF: SQLite Runtime Status {F17200} ** ** This interface is used to retrieve run-time status information ** about the preformance of SQLite, and optionally to reset various ** highwater marks. The first argument is an integer code for | > | 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 | #define SQLITE_TESTCTRL_FAULT_FAILURES 2 #define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES 3 #define SQLITE_TESTCTRL_FAULT_PENDING 4 #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 /* ** CAPI3REF: SQLite Runtime Status {F17200} ** ** This interface is used to retrieve run-time status information ** about the preformance of SQLite, and optionally to reset various ** highwater marks. The first argument is an integer code for |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.718 2008/06/19 18:17:50 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 | void sqlite3FaultConfig(int,int,int); int sqlite3FaultFailures(int); int sqlite3FaultBenignFailures(int); int sqlite3FaultPending(int); void sqlite3FaultBeginBenign(int); void sqlite3FaultEndBenign(int); int sqlite3FaultStep(int); #else # define sqlite3FaultConfig(A,B,C) # define sqlite3FaultFailures(A) 0 # define sqlite3FaultBenignFailures(A) 0 # define sqlite3FaultPending(A) (-1) # define sqlite3FaultBeginBenign(A) # define sqlite3FaultEndBenign(A) | > | 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 | 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); #else # define sqlite3FaultConfig(A,B,C) # define sqlite3FaultFailures(A) 0 # define sqlite3FaultBenignFailures(A) 0 # define sqlite3FaultPending(A) (-1) # define sqlite3FaultBeginBenign(A) # define sqlite3FaultEndBenign(A) |
︙ | ︙ |
Changes to src/test_malloc.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** | | > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** 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 $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> const char *sqlite3TestErrorName(int); /* ** Transform pointers to text and back again */ static void pointerToText(void *p, char *z){ static const char zHex[] = "0123456789abcdef"; int i, k; |
︙ | ︙ | |||
775 776 777 778 779 780 781 782 783 784 785 786 787 788 | pResult = Tcl_NewObj(); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue)); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue)); Tcl_SetObjResult(interp, pResult); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ static struct { char *zName; | > > > > > > > > > > > > > > > > > > > > > > > > | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | pResult = Tcl_NewObj(); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue)); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue)); Tcl_SetObjResult(interp, pResult); 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. */ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ static struct { char *zName; |
︙ | ︙ | |||
801 802 803 804 805 806 807 808 809 810 811 812 813 814 | { "sqlite3_memdebug_pending", test_memdebug_pending }, { "sqlite3_memdebug_settitle", test_memdebug_settitle }, { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count }, { "sqlite3_memdebug_log", test_memdebug_log }, { "sqlite3_config_scratch", test_config_scratch }, { "sqlite3_config_pagecache", test_config_pagecache }, { "sqlite3_status", test_status }, }; int i; for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } return TCL_OK; } | > > | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 | { "sqlite3_memdebug_pending", test_memdebug_pending }, { "sqlite3_memdebug_settitle", test_memdebug_settitle }, { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count }, { "sqlite3_memdebug_log", test_memdebug_log }, { "sqlite3_config_scratch", test_config_scratch }, { "sqlite3_config_pagecache", test_config_pagecache }, { "sqlite3_status", test_status }, { "install_malloc_faultsim", test_install_malloc_faultsim }, }; int i; for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } return TCL_OK; } |
Changes to test/malloc.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # This file attempts to check the behavior of the SQLite library in # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) # 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. # | | > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # This file attempts to check the behavior of the SQLite library in # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) # 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: malloc.test,v 1.62 2008/06/19 18:17:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # source $testdir/malloc_common.tcl if {!$MEMDEBUG} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." finish_test |
︙ | ︙ |
Changes to test/malloc2.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # This file attempts to check that the library can recover from a malloc() # failure when sqlite3_global_recover() is invoked. # # (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. # | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # This file attempts to check that the library can recover from a malloc() # failure when sqlite3_global_recover() is invoked. # # (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.13 2008/06/19 18:17:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl # Only run these tests if memory debugging is turned on. # if {!$MEMDEBUG} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." finish_test return } sqlite3_extended_result_codes db 1 proc do_malloc2_test {tn args} { array set ::mallocopts $args set sum [allcksum db] save_prng_state for {set ::n 1} {true} {incr ::n} { # Run the SQL. Malloc number $::n is set to fail. A malloc() failure # may or may not be reported. restore_prng_state sqlite3_memdebug_fail $::n -repeat 1 do_test malloc2-$tn.$::n.2 { set res [catchsql [string trim $::mallocopts(-sql)]] |
︙ | ︙ |
Changes to test/malloc_common.tcl.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains common code used by many different malloc tests # within the test suite. # | | > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains common code used by many different malloc tests # within the test suite. # # $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. # ifcapable builtin_test { set MEMDEBUG 1 } else { set MEMDEBUG 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...> # # 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. |
︙ | ︙ |