summaryrefslogtreecommitdiff
path: root/chromium/third_party/sqlite/sqlite-src-3240000/src/test_malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/sqlite/sqlite-src-3240000/src/test_malloc.c')
-rw-r--r--chromium/third_party/sqlite/sqlite-src-3240000/src/test_malloc.c1546
1 files changed, 0 insertions, 1546 deletions
diff --git a/chromium/third_party/sqlite/sqlite-src-3240000/src/test_malloc.c b/chromium/third_party/sqlite/sqlite-src-3240000/src/test_malloc.c
deleted file mode 100644
index 32a03e71911..00000000000
--- a/chromium/third_party/sqlite/sqlite-src-3240000/src/test_malloc.c
+++ /dev/null
@@ -1,1546 +0,0 @@
-/*
-** 2007 August 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.
-**
-*************************************************************************
-**
-** This file contains code used to implement test interfaces to the
-** memory allocation subsystem.
-*/
-#include "sqliteInt.h"
-#if defined(INCLUDE_SQLITE_TCL_H)
-# include "sqlite_tcl.h"
-#else
-# include "tcl.h"
-#endif
-#include <stdlib.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 */
- int nOkBefore; /* Successful allocations prior to the first fault */
- int nOkAfter; /* Successful allocations after a fault */
- u8 enable; /* True if enabled */
- int isInstalled; /* True if the fault simulation layer is installed */
- int isBenignMode; /* True if malloc failures are considered benign */
- 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++;
-}
-
-/*
-** This routine exists as a place to set a breakpoint that will
-** fire the first time any malloc() fails on a single test case.
-** The sqlite3Fault() routine above runs on every malloc() failure.
-** This routine only runs on the first such failure.
-*/
-static void sqlite3FirstFault(void){
- static int cnt2 = 0;
- cnt2++;
-}
-
-/*
-** 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(void){
- if( likely(!memfault.enable) ){
- memfault.nOkAfter++;
- return 0;
- }
- if( memfault.iCountdown>0 ){
- memfault.iCountdown--;
- memfault.nOkBefore++;
- return 0;
- }
- if( memfault.nFail==0 ) sqlite3FirstFault();
- sqlite3Fault();
- memfault.nFail++;
- if( memfault.isBenignMode>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.nOkBefore = 0;
- memfault.nOkAfter = 0;
- memfault.enable = nDelay>=0;
-
- /* Sometimes, when running multi-threaded tests, the isBenignMode
- ** variable is not properly incremented/decremented so that it is
- ** 0 when not inside a benign malloc block. This doesn't affect
- ** the multi-threaded tests, as they do not use this system. But
- ** it does affect OOM tests run later in the same process. So
- ** zero the variable here, just to be sure.
- */
- memfault.isBenignMode = 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;
- }
-}
-
-
-static void faultsimBeginBenign(void){
- memfault.isBenignMode++;
-}
-static void faultsimEndBenign(void){
- memfault.isBenignMode--;
-}
-
-/*
-** 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;
- }
-
- if( install ){
- rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
- assert(memfault.m.xMalloc);
- if( rc==SQLITE_OK ){
- rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
- }
- sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,
- faultsimBeginBenign, faultsimEndBenign
- );
- }else{
- sqlite3_mem_methods m2;
- assert(memfault.m.xMalloc);
-
- /* One should be able to reset the default memory allocator by storing
- ** a zeroed allocator then calling GETMALLOC. */
- memset(&m2, 0, sizeof(m2));
- sqlite3_config(SQLITE_CONFIG_MALLOC, &m2);
- sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m2);
- assert( memcmp(&m2, &memfault.m, sizeof(m2))==0 );
-
- rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
- sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,
- (void*)0, (void*)0);
- }
-
- if( rc==SQLITE_OK ){
- memfault.isInstalled = 1;
- }
- return rc;
-}
-
-#ifdef SQLITE_TEST
-
-/*
-** This function is implemented in main.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:
-**
-** sqlite3ErrName(1) -> "SQLITE_ERROR"
-*/
-extern const char *sqlite3ErrName(int);
-
-/*
-** Transform pointers to text and back again
-*/
-static void pointerToText(void *p, char *z){
- static const char zHex[] = "0123456789abcdef";
- int i, k;
- unsigned int u;
- sqlite3_uint64 n;
- if( p==0 ){
- strcpy(z, "0");
- return;
- }
- if( sizeof(n)==sizeof(p) ){
- memcpy(&n, &p, sizeof(p));
- }else if( sizeof(u)==sizeof(p) ){
- memcpy(&u, &p, sizeof(u));
- n = u;
- }else{
- assert( 0 );
- }
- for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){
- z[k] = zHex[n&0xf];
- n >>= 4;
- }
- z[sizeof(p)*2] = 0;
-}
-static int hexToInt(int h){
- if( h>='0' && h<='9' ){
- return h - '0';
- }else if( h>='a' && h<='f' ){
- return h - 'a' + 10;
- }else{
- return -1;
- }
-}
-static int textToPointer(const char *z, void **pp){
- sqlite3_uint64 n = 0;
- int i;
- unsigned int u;
- for(i=0; i<sizeof(void*)*2 && z[0]; i++){
- int v;
- v = hexToInt(*z++);
- if( v<0 ) return TCL_ERROR;
- n = n*16 + v;
- }
- if( *z!=0 ) return TCL_ERROR;
- if( sizeof(n)==sizeof(*pp) ){
- memcpy(pp, &n, sizeof(n));
- }else if( sizeof(u)==sizeof(*pp) ){
- u = (unsigned int)n;
- memcpy(pp, &u, sizeof(u));
- }else{
- assert( 0 );
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_malloc NBYTES
-**
-** Raw test interface for sqlite3_malloc().
-*/
-static int SQLITE_TCLAPI test_malloc(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int nByte;
- void *p;
- char zOut[100];
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "NBYTES");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &nByte) ) return TCL_ERROR;
- p = sqlite3_malloc((unsigned)nByte);
- pointerToText(p, zOut);
- Tcl_AppendResult(interp, zOut, NULL);
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_realloc PRIOR NBYTES
-**
-** Raw test interface for sqlite3_realloc().
-*/
-static int SQLITE_TCLAPI test_realloc(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int nByte;
- void *pPrior, *p;
- char zOut[100];
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "PRIOR NBYTES");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &nByte) ) return TCL_ERROR;
- if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){
- Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
- return TCL_ERROR;
- }
- p = sqlite3_realloc(pPrior, (unsigned)nByte);
- pointerToText(p, zOut);
- Tcl_AppendResult(interp, zOut, NULL);
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_free PRIOR
-**
-** Raw test interface for sqlite3_free().
-*/
-static int SQLITE_TCLAPI test_free(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- void *pPrior;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "PRIOR");
- return TCL_ERROR;
- }
- if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){
- Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
- return TCL_ERROR;
- }
- sqlite3_free(pPrior);
- return TCL_OK;
-}
-
-/*
-** These routines are in test_hexio.c
-*/
-int sqlite3TestHexToBin(const char *, int, char *);
-int sqlite3TestBinToHex(char*,int);
-
-/*
-** Usage: memset ADDRESS SIZE HEX
-**
-** Set a chunk of memory (obtained from malloc, probably) to a
-** specified hex pattern.
-*/
-static int SQLITE_TCLAPI test_memset(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- void *p;
- int size, n, i;
- char *zHex;
- char *zOut;
- char zBin[100];
-
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX");
- return TCL_ERROR;
- }
- if( textToPointer(Tcl_GetString(objv[1]), &p) ){
- Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &size) ){
- return TCL_ERROR;
- }
- if( size<=0 ){
- Tcl_AppendResult(interp, "size must be positive", (char*)0);
- return TCL_ERROR;
- }
- zHex = Tcl_GetStringFromObj(objv[3], &n);
- if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2;
- n = sqlite3TestHexToBin(zHex, n, zBin);
- if( n==0 ){
- Tcl_AppendResult(interp, "no data", (char*)0);
- return TCL_ERROR;
- }
- zOut = p;
- for(i=0; i<size; i++){
- zOut[i] = zBin[i%n];
- }
- return TCL_OK;
-}
-
-/*
-** Usage: memget ADDRESS SIZE
-**
-** Return memory as hexadecimal text.
-*/
-static int SQLITE_TCLAPI test_memget(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- void *p;
- int size, n;
- char *zBin;
- char zHex[100];
-
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE");
- return TCL_ERROR;
- }
- if( textToPointer(Tcl_GetString(objv[1]), &p) ){
- Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &size) ){
- return TCL_ERROR;
- }
- if( size<=0 ){
- Tcl_AppendResult(interp, "size must be positive", (char*)0);
- return TCL_ERROR;
- }
- zBin = p;
- while( size>0 ){
- if( size>(sizeof(zHex)-1)/2 ){
- n = (sizeof(zHex)-1)/2;
- }else{
- n = size;
- }
- memcpy(zHex, zBin, n);
- zBin += n;
- size -= n;
- sqlite3TestBinToHex(zHex, n);
- Tcl_AppendResult(interp, zHex, (char*)0);
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_memory_used
-**
-** Raw test interface for sqlite3_memory_used().
-*/
-static int SQLITE_TCLAPI test_memory_used(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_memory_used()));
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_memory_highwater ?RESETFLAG?
-**
-** Raw test interface for sqlite3_memory_highwater().
-*/
-static int SQLITE_TCLAPI test_memory_highwater(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int resetFlag = 0;
- if( objc!=1 && objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "?RESET?");
- return TCL_ERROR;
- }
- if( objc==2 ){
- if( Tcl_GetBooleanFromObj(interp, objv[1], &resetFlag) ) return TCL_ERROR;
- }
- Tcl_SetObjResult(interp,
- Tcl_NewWideIntObj(sqlite3_memory_highwater(resetFlag)));
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_memdebug_backtrace DEPTH
-**
-** Set the depth of backtracing. If SQLITE_MEMDEBUG is not defined
-** then this routine is a no-op.
-*/
-static int SQLITE_TCLAPI test_memdebug_backtrace(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int depth;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "DEPT");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &depth) ) return TCL_ERROR;
-#ifdef SQLITE_MEMDEBUG
- {
- extern void sqlite3MemdebugBacktrace(int);
- sqlite3MemdebugBacktrace(depth);
- }
-#endif
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_memdebug_dump FILENAME
-**
-** Write a summary of unfreed memory to FILENAME.
-*/
-static int SQLITE_TCLAPI test_memdebug_dump(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
- return TCL_ERROR;
- }
-#if defined(SQLITE_MEMDEBUG) || defined(SQLITE_MEMORY_SIZE) \
- || defined(SQLITE_POW2_MEMORY_SIZE)
- {
- extern void sqlite3MemdebugDump(const char*);
- sqlite3MemdebugDump(Tcl_GetString(objv[1]));
- }
-#endif
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_memdebug_malloc_count
-**
-** Return the total number of times malloc() has been called.
-*/
-static int SQLITE_TCLAPI test_memdebug_malloc_count(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int nMalloc = -1;
- if( objc!=1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "");
- return TCL_ERROR;
- }
-#if defined(SQLITE_MEMDEBUG)
- {
- extern int sqlite3MemdebugMallocCount();
- nMalloc = sqlite3MemdebugMallocCount();
- }
-#endif
- Tcl_SetObjResult(interp, Tcl_NewIntObj(nMalloc));
- return TCL_OK;
-}
-
-
-/*
-** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS?
-**
-** where options are:
-**
-** -repeat <count>
-** -benigncnt <varname>
-**
-** Arrange for a simulated malloc() failure after COUNTER successes.
-** If a repeat count is specified, the fault is repeated that many
-** times.
-**
-** Each call to this routine overrides the prior counter value.
-** This routine returns the number of simulated failures that have
-** happened since the previous call to this routine.
-**
-** To disable simulated failures, use a COUNTER of -1.
-*/
-static int SQLITE_TCLAPI test_memdebug_fail(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int ii;
- int iFail;
- int nRepeat = 1;
- Tcl_Obj *pBenignCnt = 0;
- int nBenign;
- int nFail = 0;
-
- if( objc<2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR;
-
- for(ii=2; ii<objc; ii+=2){
- int nOption;
- char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption);
- char *zErr = 0;
-
- if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){
- if( ii==(objc-1) ){
- zErr = "option requires an argument: ";
- }else{
- if( Tcl_GetIntFromObj(interp, objv[ii+1], &nRepeat) ){
- return TCL_ERROR;
- }
- }
- }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){
- if( ii==(objc-1) ){
- zErr = "option requires an argument: ";
- }else{
- pBenignCnt = objv[ii+1];
- }
- }else{
- zErr = "unknown option: ";
- }
-
- if( zErr ){
- Tcl_AppendResult(interp, zErr, zOption, 0);
- return TCL_ERROR;
- }
- }
-
- nBenign = faultsimBenignFailures();
- nFail = faultsimFailures();
- faultsimConfig(iFail, nRepeat);
-
- if( pBenignCnt ){
- Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(nBenign), 0);
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail));
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_memdebug_pending
-**
-** Return the number of malloc() calls that will succeed before a
-** simulated failure occurs. A negative return value indicates that
-** no malloc() failure is scheduled.
-*/
-static int SQLITE_TCLAPI test_memdebug_pending(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int nPending;
- if( objc!=1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "");
- return TCL_ERROR;
- }
- nPending = faultsimPending();
- Tcl_SetObjResult(interp, Tcl_NewIntObj(nPending));
- return TCL_OK;
-}
-
-/*
-** The following global variable keeps track of the number of tests
-** that have run. This variable is only useful when running in the
-** debugger.
-*/
-static int sqlite3_memdebug_title_count = 0;
-
-/*
-** Usage: sqlite3_memdebug_settitle TITLE
-**
-** Set a title string stored with each allocation. The TITLE is
-** typically the name of the test that was running when the
-** allocation occurred. The TITLE is stored with the allocation
-** and can be used to figure out which tests are leaking memory.
-**
-** Each title overwrite the previous.
-*/
-static int SQLITE_TCLAPI test_memdebug_settitle(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- sqlite3_memdebug_title_count++;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "TITLE");
- return TCL_ERROR;
- }
-#ifdef SQLITE_MEMDEBUG
- {
- const char *zTitle;
- extern int sqlite3MemdebugSettitle(const char*);
- zTitle = Tcl_GetString(objv[1]);
- sqlite3MemdebugSettitle(zTitle);
- }
-#endif
- return TCL_OK;
-}
-
-#define MALLOC_LOG_FRAMES 10
-#define MALLOC_LOG_KEYINTS ( \
- 10 * ((sizeof(int)>=sizeof(void*)) ? 1 : sizeof(void*)/sizeof(int)) \
-)
-static Tcl_HashTable aMallocLog;
-static int mallocLogEnabled = 0;
-
-typedef struct MallocLog MallocLog;
-struct MallocLog {
- int nCall;
- int nByte;
-};
-
-#ifdef SQLITE_MEMDEBUG
-static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
- if( mallocLogEnabled ){
- MallocLog *pLog;
- Tcl_HashEntry *pEntry;
- int isNew;
-
- int aKey[MALLOC_LOG_KEYINTS];
- unsigned int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
-
- memset(aKey, 0, nKey);
- if( (sizeof(void*)*nFrame)<nKey ){
- nKey = nFrame*sizeof(void*);
- }
- memcpy(aKey, aFrame, nKey);
-
- pEntry = Tcl_CreateHashEntry(&aMallocLog, (const char *)aKey, &isNew);
- if( isNew ){
- pLog = (MallocLog *)Tcl_Alloc(sizeof(MallocLog));
- memset(pLog, 0, sizeof(MallocLog));
- Tcl_SetHashValue(pEntry, (ClientData)pLog);
- }else{
- pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
- }
-
- pLog->nCall++;
- pLog->nByte += nByte;
- }
-}
-#endif /* SQLITE_MEMDEBUG */
-
-static void test_memdebug_log_clear(void){
- Tcl_HashSearch search;
- Tcl_HashEntry *pEntry;
- for(
- pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
- pEntry;
- pEntry=Tcl_NextHashEntry(&search)
- ){
- MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
- Tcl_Free((char *)pLog);
- }
- Tcl_DeleteHashTable(&aMallocLog);
- Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
-}
-
-static int SQLITE_TCLAPI test_memdebug_log(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- static int isInit = 0;
- int iSub;
-
- static const char *MB_strs[] = { "start", "stop", "dump", "clear", "sync" };
- enum MB_enum {
- MB_LOG_START, MB_LOG_STOP, MB_LOG_DUMP, MB_LOG_CLEAR, MB_LOG_SYNC
- };
-
- if( !isInit ){
-#ifdef SQLITE_MEMDEBUG
- extern void sqlite3MemdebugBacktraceCallback(
- void (*xBacktrace)(int, int, void **));
- sqlite3MemdebugBacktraceCallback(test_memdebug_callback);
-#endif
- Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
- isInit = 1;
- }
-
- if( objc<2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
- }
- if( Tcl_GetIndexFromObj(interp, objv[1], MB_strs, "sub-command", 0, &iSub) ){
- return TCL_ERROR;
- }
-
- switch( (enum MB_enum)iSub ){
- case MB_LOG_START:
- mallocLogEnabled = 1;
- break;
- case MB_LOG_STOP:
- mallocLogEnabled = 0;
- break;
- case MB_LOG_DUMP: {
- Tcl_HashSearch search;
- Tcl_HashEntry *pEntry;
- Tcl_Obj *pRet = Tcl_NewObj();
-
- assert(sizeof(Tcl_WideInt)>=sizeof(void*));
-
- for(
- pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
- pEntry;
- pEntry=Tcl_NextHashEntry(&search)
- ){
- Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2];
- MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
- Tcl_WideInt *aKey = (Tcl_WideInt *)Tcl_GetHashKey(&aMallocLog, pEntry);
- int ii;
-
- apElem[0] = Tcl_NewIntObj(pLog->nCall);
- apElem[1] = Tcl_NewIntObj(pLog->nByte);
- for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){
- apElem[ii+2] = Tcl_NewWideIntObj(aKey[ii]);
- }
-
- Tcl_ListObjAppendElement(interp, pRet,
- Tcl_NewListObj(MALLOC_LOG_FRAMES+2, apElem)
- );
- }
-
- Tcl_SetObjResult(interp, pRet);
- break;
- }
- case MB_LOG_CLEAR: {
- test_memdebug_log_clear();
- break;
- }
-
- case MB_LOG_SYNC: {
-#ifdef SQLITE_MEMDEBUG
- extern void sqlite3MemdebugSync();
- test_memdebug_log_clear();
- mallocLogEnabled = 1;
- sqlite3MemdebugSync();
-#endif
- break;
- }
- }
-
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_pagecache SIZE N
-**
-** Set the page-cache memory buffer using SQLITE_CONFIG_PAGECACHE.
-** The buffer is static and is of limited size. N might be
-** adjusted downward as needed to accommodate the requested size.
-** The revised value of N is returned.
-**
-** A negative SIZE causes the buffer pointer to be NULL.
-*/
-static int SQLITE_TCLAPI test_config_pagecache(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int sz, N;
- Tcl_Obj *pRes;
- static char *buf = 0;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "SIZE N");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR;
- free(buf);
- buf = 0;
-
- /* Set the return value */
- pRes = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewIntObj(sqlite3GlobalConfig.szPage));
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewIntObj(sqlite3GlobalConfig.nPage));
- Tcl_SetObjResult(interp, pRes);
-
- if( sz<0 ){
- sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, 0);
- }else{
- buf = malloc( sz*N );
- sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N);
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_alt_pcache INSTALL_FLAG DISCARD_CHANCE PRNG_SEED
-**
-** Set up the alternative test page cache. Install if INSTALL_FLAG is
-** true and uninstall (reverting to the default page cache) if INSTALL_FLAG
-** is false. DISCARD_CHANGE is an integer between 0 and 100 inclusive
-** which determines the chance of discarding a page when unpinned. 100
-** is certainty. 0 is never. PRNG_SEED is the pseudo-random number generator
-** seed.
-*/
-static int SQLITE_TCLAPI test_alt_pcache(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int installFlag;
- int discardChance = 0;
- int prngSeed = 0;
- int highStress = 0;
- extern void installTestPCache(int,unsigned,unsigned,unsigned);
- if( objc<2 || objc>5 ){
- Tcl_WrongNumArgs(interp, 1, objv,
- "INSTALLFLAG DISCARDCHANCE PRNGSEEED HIGHSTRESS");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &installFlag) ) return TCL_ERROR;
- if( objc>=3 && Tcl_GetIntFromObj(interp, objv[2], &discardChance) ){
- return TCL_ERROR;
- }
- if( objc>=4 && Tcl_GetIntFromObj(interp, objv[3], &prngSeed) ){
- return TCL_ERROR;
- }
- if( objc>=5 && Tcl_GetIntFromObj(interp, objv[4], &highStress) ){
- return TCL_ERROR;
- }
- if( discardChance<0 || discardChance>100 ){
- Tcl_AppendResult(interp, "discard-chance should be between 0 and 100",
- (char*)0);
- return TCL_ERROR;
- }
- installTestPCache(installFlag, (unsigned)discardChance, (unsigned)prngSeed,
- (unsigned)highStress);
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_memstatus BOOLEAN
-**
-** Enable or disable memory status reporting using SQLITE_CONFIG_MEMSTATUS.
-*/
-static int SQLITE_TCLAPI test_config_memstatus(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int enable, rc;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ) return TCL_ERROR;
- rc = sqlite3_config(SQLITE_CONFIG_MEMSTATUS, enable);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_lookaside SIZE COUNT
-**
-*/
-static int SQLITE_TCLAPI test_config_lookaside(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int sz, cnt;
- Tcl_Obj *pRet;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[2], &cnt) ) return TCL_ERROR;
- pRet = Tcl_NewObj();
- Tcl_ListObjAppendElement(
- interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.szLookaside)
- );
- Tcl_ListObjAppendElement(
- interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.nLookaside)
- );
- sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
- Tcl_SetObjResult(interp, pRet);
- return TCL_OK;
-}
-
-
-/*
-** Usage: sqlite3_db_config_lookaside CONNECTION BUFID SIZE COUNT
-**
-** There are two static buffers with BUFID 1 and 2. Each static buffer
-** is 10KB in size. A BUFID of 0 indicates that the buffer should be NULL
-** which will cause sqlite3_db_config() to allocate space on its own.
-*/
-static int SQLITE_TCLAPI test_db_config_lookaside(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc;
- int sz, cnt;
- sqlite3 *db;
- int bufid;
- static char azBuf[2][10000];
- extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BUFID SIZE COUNT");
- return TCL_ERROR;
- }
- if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[2], &bufid) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR;
- if( bufid==0 ){
- rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, (void*)0, sz, cnt);
- }else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){
- rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt);
- }else{
- Tcl_AppendResult(interp, "illegal arguments - see documentation", (char*)0);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_heap NBYTE NMINALLOC
-*/
-static int SQLITE_TCLAPI test_config_heap(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- static char *zBuf; /* Use this memory */
- int nByte; /* Size of buffer to pass to sqlite3_config() */
- int nMinAlloc; /* Size of minimum allocation */
- int rc; /* Return code of sqlite3_config() */
-
- Tcl_Obj * CONST *aArg = &objv[1];
- int nArg = objc-1;
-
- if( nArg!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "NBYTE NMINALLOC");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, aArg[1], &nMinAlloc) ) return TCL_ERROR;
-
- if( nByte==0 ){
- free( zBuf );
- zBuf = 0;
- rc = sqlite3_config(SQLITE_CONFIG_HEAP, (void*)0, 0, 0);
- }else{
- zBuf = realloc(zBuf, nByte);
- rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc);
- }
-
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_heap_size NBYTE
-*/
-static int SQLITE_TCLAPI test_config_heap_size(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int nByte; /* Size to pass to sqlite3_config() */
- int rc; /* Return code of sqlite3_config() */
-
- Tcl_Obj * CONST *aArg = &objv[1];
- int nArg = objc-1;
-
- if( nArg!=1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "NBYTE");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR;
-
- rc = sqlite3_config(SQLITE_CONFIG_WIN32_HEAPSIZE, nByte);
-
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_error [DB]
-**
-** Invoke sqlite3_config() or sqlite3_db_config() with invalid
-** opcodes and verify that they return errors.
-*/
-static int SQLITE_TCLAPI test_config_error(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- sqlite3 *db;
- extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
-
- if( objc!=2 && objc!=1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "[DB]");
- return TCL_ERROR;
- }
- if( objc==2 ){
- if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
- if( sqlite3_db_config(db, 99999)!=SQLITE_ERROR ){
- Tcl_AppendResult(interp,
- "sqlite3_db_config(db, 99999) does not return SQLITE_ERROR",
- (char*)0);
- return TCL_ERROR;
- }
- }else{
- if( sqlite3_config(99999)!=SQLITE_ERROR ){
- Tcl_AppendResult(interp,
- "sqlite3_config(99999) does not return SQLITE_ERROR",
- (char*)0);
- return TCL_ERROR;
- }
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_uri BOOLEAN
-**
-** Enables or disables interpretation of URI parameters by default using
-** SQLITE_CONFIG_URI.
-*/
-static int SQLITE_TCLAPI test_config_uri(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc;
- int bOpenUri;
-
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[1], &bOpenUri) ){
- return TCL_ERROR;
- }
-
- rc = sqlite3_config(SQLITE_CONFIG_URI, bOpenUri);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
-
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_cis BOOLEAN
-**
-** Enables or disables the use of the covering-index scan optimization.
-** SQLITE_CONFIG_COVERING_INDEX_SCAN.
-*/
-static int SQLITE_TCLAPI test_config_cis(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc;
- int bUseCis;
-
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[1], &bUseCis) ){
- return TCL_ERROR;
- }
-
- rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
-
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_config_pmasz INTEGER
-**
-** Set the minimum PMA size.
-*/
-static int SQLITE_TCLAPI test_config_pmasz(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc;
- int iPmaSz;
-
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[1], &iPmaSz) ){
- return TCL_ERROR;
- }
-
- rc = sqlite3_config(SQLITE_CONFIG_PMASZ, iPmaSz);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
-
- return TCL_OK;
-}
-
-
-/*
-** Usage: sqlite3_dump_memsys3 FILENAME
-** sqlite3_dump_memsys5 FILENAME
-**
-** Write a summary of unfreed memsys3 allocations to FILENAME.
-*/
-static int SQLITE_TCLAPI test_dump_memsys3(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
- return TCL_ERROR;
- }
-
- switch( SQLITE_PTR_TO_INT(clientData) ){
- case 3: {
-#ifdef SQLITE_ENABLE_MEMSYS3
- extern void sqlite3Memsys3Dump(const char*);
- sqlite3Memsys3Dump(Tcl_GetString(objv[1]));
- break;
-#endif
- }
- case 5: {
-#ifdef SQLITE_ENABLE_MEMSYS5
- extern void sqlite3Memsys5Dump(const char*);
- sqlite3Memsys5Dump(Tcl_GetString(objv[1]));
- break;
-#endif
- }
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3_status OPCODE RESETFLAG
-**
-** Return a list of three elements which are the sqlite3_status() return
-** code, the current value, and the high-water mark value.
-*/
-static int SQLITE_TCLAPI test_status(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc, iValue, mxValue;
- int i, op = 0, resetFlag;
- const char *zOpName;
- static const struct {
- const char *zName;
- int op;
- } aOp[] = {
- { "SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED },
- { "SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE },
- { "SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED },
- { "SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW },
- { "SQLITE_STATUS_PAGECACHE_SIZE", SQLITE_STATUS_PAGECACHE_SIZE },
- { "SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED },
- { "SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW },
- { "SQLITE_STATUS_SCRATCH_SIZE", SQLITE_STATUS_SCRATCH_SIZE },
- { "SQLITE_STATUS_PARSER_STACK", SQLITE_STATUS_PARSER_STACK },
- { "SQLITE_STATUS_MALLOC_COUNT", SQLITE_STATUS_MALLOC_COUNT },
- };
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG");
- return TCL_ERROR;
- }
- zOpName = Tcl_GetString(objv[1]);
- for(i=0; i<ArraySize(aOp); i++){
- if( strcmp(aOp[i].zName, zOpName)==0 ){
- op = aOp[i].op;
- break;
- }
- }
- if( i>=ArraySize(aOp) ){
- if( Tcl_GetIntFromObj(interp, objv[1], &op) ) return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[2], &resetFlag) ) return TCL_ERROR;
- iValue = 0;
- mxValue = 0;
- rc = sqlite3_status(op, &iValue, &mxValue, resetFlag);
- 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;
-}
-
-/*
-** Usage: sqlite3_db_status DATABASE OPCODE RESETFLAG
-**
-** Return a list of three elements which are the sqlite3_db_status() return
-** code, the current value, and the high-water mark value.
-*/
-static int SQLITE_TCLAPI test_db_status(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc, iValue, mxValue;
- int i, op = 0, resetFlag;
- const char *zOpName;
- sqlite3 *db;
- extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
- static const struct {
- const char *zName;
- int op;
- } aOp[] = {
- { "LOOKASIDE_USED", SQLITE_DBSTATUS_LOOKASIDE_USED },
- { "CACHE_USED", SQLITE_DBSTATUS_CACHE_USED },
- { "SCHEMA_USED", SQLITE_DBSTATUS_SCHEMA_USED },
- { "STMT_USED", SQLITE_DBSTATUS_STMT_USED },
- { "LOOKASIDE_HIT", SQLITE_DBSTATUS_LOOKASIDE_HIT },
- { "LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE },
- { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL },
- { "CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT },
- { "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS },
- { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE },
- { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS },
- { "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED },
- { "CACHE_SPILL", SQLITE_DBSTATUS_CACHE_SPILL },
- };
- Tcl_Obj *pResult;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "DB PARAMETER RESETFLAG");
- return TCL_ERROR;
- }
- if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
- zOpName = Tcl_GetString(objv[2]);
- if( memcmp(zOpName, "SQLITE_", 7)==0 ) zOpName += 7;
- if( memcmp(zOpName, "DBSTATUS_", 9)==0 ) zOpName += 9;
- for(i=0; i<ArraySize(aOp); i++){
- if( strcmp(aOp[i].zName, zOpName)==0 ){
- op = aOp[i].op;
- break;
- }
- }
- if( i>=ArraySize(aOp) ){
- if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
- iValue = 0;
- mxValue = 0;
- rc = sqlite3_db_status(db, op, &iValue, &mxValue, resetFlag);
- 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 SQLITE_TCLAPI 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 = faultsimInstall(isInstall);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
- return TCL_OK;
-}
-
-/*
-** sqlite3_install_memsys3
-*/
-static int SQLITE_TCLAPI test_install_memsys3(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc = SQLITE_MISUSE;
-#ifdef SQLITE_ENABLE_MEMSYS3
- const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
- rc = sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetMemsys3());
-#endif
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
- return TCL_OK;
-}
-
-static int SQLITE_TCLAPI test_vfs_oom_test(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- extern int sqlite3_memdebug_vfs_oom_test;
- if( objc>2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "?INTEGER?");
- return TCL_ERROR;
- }else if( objc==2 ){
- int iNew;
- if( Tcl_GetIntFromObj(interp, objv[1], &iNew) ) return TCL_ERROR;
- sqlite3_memdebug_vfs_oom_test = iNew;
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_vfs_oom_test));
- return TCL_OK;
-}
-
-/*
-** Register commands with the TCL interpreter.
-*/
-int Sqlitetest_malloc_Init(Tcl_Interp *interp){
- static struct {
- char *zName;
- Tcl_ObjCmdProc *xProc;
- int clientData;
- } aObjCmd[] = {
- { "sqlite3_malloc", test_malloc ,0 },
- { "sqlite3_realloc", test_realloc ,0 },
- { "sqlite3_free", test_free ,0 },
- { "memset", test_memset ,0 },
- { "memget", test_memget ,0 },
- { "sqlite3_memory_used", test_memory_used ,0 },
- { "sqlite3_memory_highwater", test_memory_highwater ,0 },
- { "sqlite3_memdebug_backtrace", test_memdebug_backtrace ,0 },
- { "sqlite3_memdebug_dump", test_memdebug_dump ,0 },
- { "sqlite3_memdebug_fail", test_memdebug_fail ,0 },
- { "sqlite3_memdebug_pending", test_memdebug_pending ,0 },
- { "sqlite3_memdebug_settitle", test_memdebug_settitle ,0 },
- { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0 },
- { "sqlite3_memdebug_log", test_memdebug_log ,0 },
- { "sqlite3_config_pagecache", test_config_pagecache ,0 },
- { "sqlite3_config_alt_pcache", test_alt_pcache ,0 },
- { "sqlite3_status", test_status ,0 },
- { "sqlite3_db_status", test_db_status ,0 },
- { "install_malloc_faultsim", test_install_malloc_faultsim ,0 },
- { "sqlite3_config_heap", test_config_heap ,0 },
- { "sqlite3_config_heap_size", test_config_heap_size ,0 },
- { "sqlite3_config_memstatus", test_config_memstatus ,0 },
- { "sqlite3_config_lookaside", test_config_lookaside ,0 },
- { "sqlite3_config_error", test_config_error ,0 },
- { "sqlite3_config_uri", test_config_uri ,0 },
- { "sqlite3_config_cis", test_config_cis ,0 },
- { "sqlite3_config_pmasz", test_config_pmasz ,0 },
- { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
- { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
- { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },
- { "sqlite3_install_memsys3", test_install_memsys3 ,0 },
- { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test ,0 },
- };
- int i;
- for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
- ClientData c = (ClientData)SQLITE_INT_TO_PTR(aObjCmd[i].clientData);
- Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
- }
- return TCL_OK;
-}
-#endif