15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2007 August 15
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains code used to implement test interfaces to the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** memory allocation subsystem.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tcl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This structure is used to encapsulate the global state variables used
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by malloc() fault simulation.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct MemFault {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCountdown;         /* Number of pending successes before a failure */
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nRepeat;            /* Number of times to repeat the failure */
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nBenign;            /* Number of benign failures seen since last config */
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nFail;              /* Number of failures seen since last config */
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 enable;              /* True if enabled */
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isInstalled;        /* True if the fault simulation layer is installed */
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isBenignMode;       /* True if malloc failures are considered benign */
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mem_methods m;  /* 'Real' malloc implementation */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} memfault;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine exists as a place to set a breakpoint that will
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fire on any simulated malloc() failure.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void sqlite3Fault(void){
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int cnt = 0;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cnt++;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check to see if a fault should be simulated.  Return true to simulate
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the fault.  Return false if the fault should not be simulated.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimStep(void){
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( likely(!memfault.enable) ){
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( memfault.iCountdown>0 ){
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memfault.iCountdown--;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3Fault();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.nFail++;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( memfault.isBenignMode>0 ){
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memfault.nBenign++;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.nRepeat--;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( memfault.nRepeat<=0 ){
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memfault.enable = 0;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A version of sqlite3_mem_methods.xMalloc() that includes fault simulation
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** logic.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *faultsimMalloc(int n){
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *p = 0;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !faultsimStep() ){
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p = memfault.m.xMalloc(n);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return p;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A version of sqlite3_mem_methods.xRealloc() that includes fault simulation
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** logic.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *faultsimRealloc(void *pOld, int n){
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *p = 0;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !faultsimStep() ){
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p = memfault.m.xRealloc(pOld, n);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return p;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following method calls are passed directly through to the underlying
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** malloc system:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     xFree
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     xSize
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     xRoundup
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     xInit
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     xShutdown
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimFree(void *p){
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.m.xFree(p);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimSize(void *p){
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memfault.m.xSize(p);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimRoundup(int n){
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memfault.m.xRoundup(n);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimInit(void *p){
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memfault.m.xInit(memfault.m.pAppData);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimShutdown(void *p){
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.m.xShutdown(memfault.m.pAppData);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine configures the malloc failure simulation.  After
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** calling this routine, the next nDelay mallocs will succeed, followed
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by a block of nRepeat failures, after which malloc() calls will begin
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to succeed again.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimConfig(int nDelay, int nRepeat){
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.iCountdown = nDelay;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.nRepeat = nRepeat;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.nBenign = 0;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.nFail = 0;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.enable = nDelay>=0;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Sometimes, when running multi-threaded tests, the isBenignMode
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** variable is not properly incremented/decremented so that it is
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** 0 when not inside a benign malloc block. This doesn't affect
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** the multi-threaded tests, as they do not use this system. But
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** it does affect OOM tests run later in the same process. So
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** zero the variable here, just to be sure.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.isBenignMode = 0;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of faults (both hard and benign faults) that have
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** occurred since the injector was last configured.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimFailures(void){
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memfault.nFail;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of benign faults that have occurred since the
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** injector was last configured.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimBenignFailures(void){
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memfault.nBenign;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of successes that will occur before the next failure.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If no failures are scheduled, return -1.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimPending(void){
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( memfault.enable ){
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return memfault.iCountdown;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimBeginBenign(void){
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.isBenignMode++;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void faultsimEndBenign(void){
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memfault.isBenignMode--;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Add or remove the fault-simulation layer using sqlite3_config(). If
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the argument is non-zero, the
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int faultsimInstall(int install){
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct sqlite3_mem_methods m = {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimMalloc,                   /* xMalloc */
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimFree,                     /* xFree */
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimRealloc,                  /* xRealloc */
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimSize,                     /* xSize */
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimRoundup,                  /* xRoundup */
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimInit,                     /* xInit */
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faultsimShutdown,                 /* xShutdown */
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0                                 /* pAppData */
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  install = (install ? 1 : 0);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(memfault.isInstalled==1 || memfault.isInstalled==0);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( install==memfault.isInstalled ){
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SQLITE_ERROR;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( install ){
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memfault.m);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(memfault.m.xMalloc);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( rc==SQLITE_OK ){
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        faultsimBeginBenign, faultsimEndBenign
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    );
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_mem_methods m;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(memfault.m.xMalloc);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* One should be able to reset the default memory allocator by storing
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** a zeroed allocator then calling GETMALLOC. */
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&m, 0, sizeof(m));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( memcmp(&m, &memfault.m, sizeof(m))==0 );
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memfault.isInstalled = 1;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function is implemented in test1.c. Returns a pointer to a static
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** buffer containing the symbolic SQLite error code that corresponds to
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the least-significant 8-bits of the integer passed as an argument.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For example:
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   sqlite3TestErrorName(1) -> "SQLITE_ERROR"
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *sqlite3TestErrorName(int);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Transform pointers to text and back again
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void pointerToText(void *p, char *z){
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char zHex[] = "0123456789abcdef";
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i, k;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int u;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_uint64 n;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( p==0 ){
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strcpy(z, "0");
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sizeof(n)==sizeof(p) ){
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&n, &p, sizeof(p));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( sizeof(u)==sizeof(p) ){
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&u, &p, sizeof(u));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n = u;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( 0 );
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    z[k] = zHex[n&0xf];
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n >>= 4;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  z[sizeof(p)*2] = 0;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int hexToInt(int h){
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( h>='0' && h<='9' ){
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return h - '0';
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( h>='a' && h<='f' ){
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return h - 'a' + 10;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int textToPointer(const char *z, void **pp){
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_uint64 n = 0;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int u;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(void*)*2 && z[0]; i++){
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int v;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v = hexToInt(*z++);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( v<0 ) return TCL_ERROR;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n = n*16 + v;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( *z!=0 ) return TCL_ERROR;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sizeof(n)==sizeof(*pp) ){
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(pp, &n, sizeof(n));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( sizeof(u)==sizeof(*pp) ){
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    u = (unsigned int)n;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(pp, &u, sizeof(u));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( 0 );
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_malloc  NBYTES
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_malloc().
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_malloc(
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nByte;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *p;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zOut[100];
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "NBYTES");
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &nByte) ) return TCL_ERROR;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  p = sqlite3_malloc((unsigned)nByte);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointerToText(p, zOut);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zOut, NULL);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_realloc  PRIOR  NBYTES
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_realloc().
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_realloc(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nByte;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *pPrior, *p;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zOut[100];
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=3 ){
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "PRIOR NBYTES");
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &nByte) ) return TCL_ERROR;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  p = sqlite3_realloc(pPrior, (unsigned)nByte);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointerToText(p, zOut);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zOut, NULL);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_free  PRIOR
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_free().
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_free(
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *pPrior;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "PRIOR");
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( textToPointer(Tcl_GetString(objv[1]), &pPrior) ){
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_free(pPrior);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** These routines are in test_hexio.c
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3TestHexToBin(const char *, int, char *);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3TestBinToHex(char*,int);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    memset  ADDRESS  SIZE  HEX
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set a chunk of memory (obtained from malloc, probably) to a
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** specified hex pattern.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memset(
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *p;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size, n, i;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zHex;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zOut;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBin[100];
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=4 ){
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX");
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( textToPointer(Tcl_GetString(objv[1]), &p) ){
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &size) ){
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( size<=0 ){
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "size must be positive", (char*)0);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zHex = Tcl_GetStringFromObj(objv[3], &n);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  n = sqlite3TestHexToBin(zHex, n, zBin);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( n==0 ){
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "no data", (char*)0);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zOut = p;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<size; i++){
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zOut[i] = zBin[i%n];
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    memget  ADDRESS  SIZE
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return memory as hexadecimal text.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memget(
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *p;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size, n;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zBin;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zHex[100];
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=3 ){
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE");
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( textToPointer(Tcl_GetString(objv[1]), &p) ){
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "bad pointer: ", Tcl_GetString(objv[1]), (char*)0);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &size) ){
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( size<=0 ){
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "size must be positive", (char*)0);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zBin = p;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while( size>0 ){
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( size>(sizeof(zHex)-1)/2 ){
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      n = (sizeof(zHex)-1)/2;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      n = size;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(zHex, zBin, n);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zBin += n;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size -= n;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3TestBinToHex(zHex, n);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, zHex, (char*)0);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memory_used
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_memory_used().
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memory_used(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_memory_used()));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memory_highwater ?RESETFLAG?
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Raw test interface for sqlite3_memory_highwater().
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memory_highwater(
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resetFlag = 0;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 && objc!=2 ){
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "?RESET?");
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc==2 ){
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( Tcl_GetBooleanFromObj(interp, objv[1], &resetFlag) ) return TCL_ERROR;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp,
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     Tcl_NewWideIntObj(sqlite3_memory_highwater(resetFlag)));
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memdebug_backtrace DEPTH
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the depth of backtracing.  If SQLITE_MEMDEBUG is not defined
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then this routine is a no-op.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_backtrace(
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int depth;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "DEPT");
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &depth) ) return TCL_ERROR;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern void sqlite3MemdebugBacktrace(int);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3MemdebugBacktrace(depth);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memdebug_dump  FILENAME
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write a summary of unfreed memory to FILENAME.
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_dump(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_MEMDEBUG) || defined(SQLITE_MEMORY_SIZE) \
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     || defined(SQLITE_POW2_MEMORY_SIZE)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern void sqlite3MemdebugDump(const char*);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3MemdebugDump(Tcl_GetString(objv[1]));
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memdebug_malloc_count
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the total number of times malloc() has been called.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_malloc_count(
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nMalloc = -1;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_MEMDEBUG)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern int sqlite3MemdebugMallocCount();
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nMalloc = sqlite3MemdebugMallocCount();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(nMalloc));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memdebug_fail  COUNTER  ?OPTIONS?
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** where options are:
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     -repeat    <count>
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     -benigncnt <varname>
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Arrange for a simulated malloc() failure after COUNTER successes.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If a repeat count is specified, the fault is repeated that many
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** times.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Each call to this routine overrides the prior counter value.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine returns the number of simulated failures that have
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** happened since the previous call to this routine.
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To disable simulated failures, use a COUNTER of -1.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_fail(
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ii;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iFail;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nRepeat = 1;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pBenignCnt = 0;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nBenign;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nFail = 0;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc<2 ){
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?");
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(ii=2; ii<objc; ii+=2){
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nOption;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zErr = 0;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( ii==(objc-1) ){
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zErr = "option requires an argument: ";
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }else{
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( Tcl_GetIntFromObj(interp, objv[ii+1], &nRepeat) ){
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return TCL_ERROR;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else if( nOption>1 && strncmp(zOption, "-benigncnt", nOption)==0 ){
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( ii==(objc-1) ){
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zErr = "option requires an argument: ";
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }else{
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pBenignCnt = objv[ii+1];
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zErr = "unknown option: ";
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( zErr ){
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_AppendResult(interp, zErr, zOption, 0);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TCL_ERROR;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nBenign = faultsimBenignFailures();
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nFail = faultsimFailures();
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  faultsimConfig(iFail, nRepeat);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pBenignCnt ){
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ObjSetVar2(interp, pBenignCnt, 0, Tcl_NewIntObj(nBenign), 0);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail));
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memdebug_pending
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the number of malloc() calls that will succeed before a
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** simulated failure occurs. A negative return value indicates that
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no malloc() failure is scheduled.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_pending(
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPending;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nPending = faultsimPending();
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(nPending));
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_memdebug_settitle TITLE
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set a title string stored with each allocation.  The TITLE is
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** typically the name of the test that was running when the
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allocation occurred.  The TITLE is stored with the allocation
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and can be used to figure out which tests are leaking memory.
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Each title overwrite the previous.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_settitle(
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zTitle;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "TITLE");
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zTitle = Tcl_GetString(objv[1]);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern int sqlite3MemdebugSettitle(const char*);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3MemdebugSettitle(zTitle);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MALLOC_LOG_FRAMES  10
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MALLOC_LOG_KEYINTS (                                              \
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    10 * ((sizeof(int)>=sizeof(void*)) ? 1 : sizeof(void*)/sizeof(int))   \
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles))
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Tcl_HashTable aMallocLog;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int mallocLogEnabled = 0;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct MallocLog MallocLog;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MallocLog {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nCall;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nByte;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( mallocLogEnabled ){
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MallocLog *pLog;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_HashEntry *pEntry;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int isNew;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int aKey[MALLOC_LOG_KEYINTS];
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nKey = sizeof(int)*MALLOC_LOG_KEYINTS;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(aKey, 0, nKey);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( (sizeof(void*)*nFrame)<nKey ){
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nKey = nFrame*sizeof(void*);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(aKey, aFrame, nKey);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pEntry = Tcl_CreateHashEntry(&aMallocLog, (const char *)aKey, &isNew);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( isNew ){
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pLog = (MallocLog *)Tcl_Alloc(sizeof(MallocLog));
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memset(pLog, 0, sizeof(MallocLog));
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_SetHashValue(pEntry, (ClientData)pLog);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pLog->nCall++;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pLog->nByte += nByte;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_MEMDEBUG */
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_memdebug_log_clear(void){
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_HashSearch search;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_HashEntry *pEntry;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pEntry;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pEntry=Tcl_NextHashEntry(&search)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ){
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_Free((char *)pLog);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_DeleteHashTable(&aMallocLog);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_memdebug_log(
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int isInit = 0;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iSub;
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char *MB_strs[] = { "start", "stop", "dump", "clear", "sync" };
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum MB_enum {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MB_LOG_START, MB_LOG_STOP, MB_LOG_DUMP, MB_LOG_CLEAR, MB_LOG_SYNC
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !isInit ){
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern void sqlite3MemdebugBacktraceCallback(
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void (*xBacktrace)(int, int, void **));
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3MemdebugBacktraceCallback(test_memdebug_callback);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS);
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    isInit = 1;
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc<2 ){
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIndexFromObj(interp, objv[1], MB_strs, "sub-command", 0, &iSub) ){
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch( (enum MB_enum)iSub ){
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MB_LOG_START:
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mallocLogEnabled = 1;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MB_LOG_STOP:
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mallocLogEnabled = 0;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MB_LOG_DUMP: {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_HashSearch search;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_HashEntry *pEntry;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_Obj *pRet = Tcl_NewObj();
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(sizeof(Tcl_WideInt)>=sizeof(void*));
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for(
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pEntry;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pEntry=Tcl_NextHashEntry(&search)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ){
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2];
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MallocLog *pLog = (MallocLog *)Tcl_GetHashValue(pEntry);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Tcl_WideInt *aKey = (Tcl_WideInt *)Tcl_GetHashKey(&aMallocLog, pEntry);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int ii;
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        apElem[0] = Tcl_NewIntObj(pLog->nCall);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        apElem[1] = Tcl_NewIntObj(pLog->nByte);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          apElem[ii+2] = Tcl_NewWideIntObj(aKey[ii]);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Tcl_ListObjAppendElement(interp, pRet,
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Tcl_NewListObj(MALLOC_LOG_FRAMES+2, apElem)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_SetObjResult(interp, pRet);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MB_LOG_CLEAR: {
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_memdebug_log_clear();
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MB_LOG_SYNC: {
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_MEMDEBUG
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extern void sqlite3MemdebugSync();
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_memdebug_log_clear();
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mallocLogEnabled = 1;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3MemdebugSync();
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_config_scratch SIZE N
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH.
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The buffer is static and is of limited size.  N might be
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** adjusted downward as needed to accomodate the requested size.
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The revised value of N is returned.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A negative SIZE causes the buffer pointer to be NULL.
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_scratch(
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sz, N, rc;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pResult;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char *buf = 0;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=3 ){
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "SIZE N");
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  free(buf);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sz<0 ){
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf = 0;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, 0, 0, 0);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf = malloc( sz*N + 1 );
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pResult = Tcl_NewObj();
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N));
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pResult);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_config_pagecache SIZE N
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the page-cache memory buffer using SQLITE_CONFIG_PAGECACHE.
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The buffer is static and is of limited size.  N might be
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** adjusted downward as needed to accomodate the requested size.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The revised value of N is returned.
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A negative SIZE causes the buffer pointer to be NULL.
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_pagecache(
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sz, N, rc;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pResult;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char *buf = 0;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=3 ){
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "SIZE N");
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  free(buf);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sz<0 ){
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf = 0;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf = malloc( sz*N );
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pResult = Tcl_NewObj();
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N));
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pResult);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_config_alt_pcache INSTALL_FLAG DISCARD_CHANCE PRNG_SEED
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set up the alternative test page cache.  Install if INSTALL_FLAG is
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** true and uninstall (reverting to the default page cache) if INSTALL_FLAG
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is false.  DISCARD_CHANGE is an integer between 0 and 100 inclusive
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** which determines the chance of discarding a page when unpinned.  100
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is certainty.  0 is never.  PRNG_SEED is the pseudo-random number generator
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** seed.
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_alt_pcache(
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int installFlag;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int discardChance = 0;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int prngSeed = 0;
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int highStress = 0;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern void installTestPCache(int,unsigned,unsigned,unsigned);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc<2 || objc>5 ){
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv,
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "INSTALLFLAG DISCARDCHANCE PRNGSEEED HIGHSTRESS");
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &installFlag) ) return TCL_ERROR;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc>=3 && Tcl_GetIntFromObj(interp, objv[2], &discardChance) ){
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return TCL_ERROR;
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc>=4 && Tcl_GetIntFromObj(interp, objv[3], &prngSeed) ){
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return TCL_ERROR;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc>=5 && Tcl_GetIntFromObj(interp, objv[4], &highStress) ){
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( discardChance<0 || discardChance>100 ){
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "discard-chance should be between 0 and 100",
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (char*)0);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  installTestPCache(installFlag, (unsigned)discardChance, (unsigned)prngSeed,
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    (unsigned)highStress);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_config_memstatus BOOLEAN
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Enable or disable memory status reporting using SQLITE_CONFIG_MEMSTATUS.
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_memstatus(
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int enable, rc;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ) return TCL_ERROR;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_config(SQLITE_CONFIG_MEMSTATUS, enable);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_config_lookaside  SIZE  COUNT
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_lookaside(
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sz, cnt;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pRet;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=3 ){
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT");
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &cnt) ) return TCL_ERROR;
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pRet = Tcl_NewObj();
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.szLookaside)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  );
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interp, pRet, Tcl_NewIntObj(sqlite3GlobalConfig.nLookaside)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  );
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pRet);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_db_config_lookaside  CONNECTION  BUFID  SIZE  COUNT
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** There are two static buffers with BUFID 1 and 2.   Each static buffer
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is 10KB in size.  A BUFID of 0 indicates that the buffer should be NULL
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** which will cause sqlite3_db_config() to allocate space on its own.
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_db_config_lookaside(
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sz, cnt;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bufid;
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char azBuf[2][10000];
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=5 ){
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "BUFID SIZE COUNT");
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[2], &bufid) ) return TCL_ERROR;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR;
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR;
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( bufid==0 ){
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt);
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "illegal arguments - see documentation", (char*)0);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   sqlite3_config_heap NBYTE NMINALLOC
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_heap(
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char *zBuf; /* Use this memory */
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int szBuf;  /* Bytes allocated for zBuf */
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nByte;         /* Size of buffer to pass to sqlite3_config() */
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nMinAlloc;     /* Size of minimum allocation */
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;            /* Return code of sqlite3_config() */
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj * CONST *aArg = &objv[1];
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg = objc-1;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( nArg!=2 ){
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "NBYTE NMINALLOC");
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR;
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIntFromObj(interp, aArg[1], &nMinAlloc) ) return TCL_ERROR;
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( nByte==0 ){
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free( zBuf );
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zBuf = 0;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    szBuf = 0;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_HEAP, (void*)0, 0, 0);
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zBuf = realloc(zBuf, nByte);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    szBuf = nByte;
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** tclcmd:     sqlite3_config_error  [DB]
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Invoke sqlite3_config() or sqlite3_db_config() with invalid
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** opcodes and verify that they return errors.
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config_error(
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 && objc!=1 ){
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "[DB]");
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc==2 ){
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3_db_config(db, 99999)!=SQLITE_ERROR ){
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_AppendResult(interp,
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "sqlite3_db_config(db, 99999) does not return SQLITE_ERROR",
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (char*)0);
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TCL_ERROR;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3_config(99999)!=SQLITE_ERROR ){
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_AppendResult(interp,
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "sqlite3_config(99999) does not return SQLITE_ERROR",
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (char*)0);
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TCL_ERROR;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   sqlite3_dump_memsys3  FILENAME
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   sqlite3_dump_memsys5  FILENAME
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write a summary of unfreed memsys3 allocations to FILENAME.
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_dump_memsys3(
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch( (int)clientData ){
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 3: {
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_MEMSYS3
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extern void sqlite3Memsys3Dump(const char*);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3Memsys3Dump(Tcl_GetString(objv[1]));
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 5: {
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_MEMSYS5
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extern void sqlite3Memsys5Dump(const char*);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3Memsys5Dump(Tcl_GetString(objv[1]));
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_status  OPCODE  RESETFLAG
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a list of three elements which are the sqlite3_status() return
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code, the current value, and the high-water mark value.
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_status(
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc, iValue, mxValue;
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i, op, resetFlag;
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zOpName;
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *zName;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int op;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aOp[] = {
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_MEMORY_USED",         SQLITE_STATUS_MEMORY_USED         },
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_MALLOC_SIZE",         SQLITE_STATUS_MALLOC_SIZE         },
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_PAGECACHE_USED",      SQLITE_STATUS_PAGECACHE_USED      },
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_PAGECACHE_OVERFLOW",  SQLITE_STATUS_PAGECACHE_OVERFLOW  },
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_PAGECACHE_SIZE",      SQLITE_STATUS_PAGECACHE_SIZE      },
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_SCRATCH_USED",        SQLITE_STATUS_SCRATCH_USED        },
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_SCRATCH_OVERFLOW",    SQLITE_STATUS_SCRATCH_OVERFLOW    },
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_SCRATCH_SIZE",        SQLITE_STATUS_SCRATCH_SIZE        },
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_PARSER_STACK",        SQLITE_STATUS_PARSER_STACK        },
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SQLITE_STATUS_MALLOC_COUNT",        SQLITE_STATUS_MALLOC_COUNT        },
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pResult;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=3 ){
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG");
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zOpName = Tcl_GetString(objv[1]);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<ArraySize(aOp); i++){
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( strcmp(aOp[i].zName, zOpName)==0 ){
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      op = aOp[i].op;
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( i>=ArraySize(aOp) ){
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( Tcl_GetIntFromObj(interp, objv[1], &op) ) return TCL_ERROR;
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetBooleanFromObj(interp, objv[2], &resetFlag) ) return TCL_ERROR;
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iValue = 0;
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mxValue = 0;
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_status(op, &iValue, &mxValue, resetFlag);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pResult = Tcl_NewObj();
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pResult);
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:    sqlite3_db_status  DATABASE  OPCODE  RESETFLAG
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a list of three elements which are the sqlite3_db_status() return
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code, the current value, and the high-water mark value.
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_db_status(
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc, iValue, mxValue;
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i, op, resetFlag;
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zOpName;
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *zName;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int op;
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aOp[] = {
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "LOOKASIDE_USED",      SQLITE_DBSTATUS_LOOKASIDE_USED      },
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "CACHE_USED",          SQLITE_DBSTATUS_CACHE_USED          },
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "SCHEMA_USED",         SQLITE_DBSTATUS_SCHEMA_USED         },
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "STMT_USED",           SQLITE_DBSTATUS_STMT_USED           },
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "LOOKASIDE_HIT",       SQLITE_DBSTATUS_LOOKASIDE_HIT       },
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE },
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL }
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pResult;
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=4 ){
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG");
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zOpName = Tcl_GetString(objv[2]);
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( memcmp(zOpName, "SQLITE_", 7)==0 ) zOpName += 7;
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( memcmp(zOpName, "DBSTATUS_", 9)==0 ) zOpName += 9;
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<ArraySize(aOp); i++){
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( strcmp(aOp[i].zName, zOpName)==0 ){
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      op = aOp[i].op;
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( i>=ArraySize(aOp) ){
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iValue = 0;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mxValue = 0;
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_db_status(db, op, &iValue, &mxValue, resetFlag);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pResult = Tcl_NewObj();
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(iValue));
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(mxValue));
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pResult);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** install_malloc_faultsim BOOLEAN
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_install_malloc_faultsim(
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isInstall;
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = faultsimInstall(isInstall);
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_install_memsys3
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_install_memsys3(
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = SQLITE_MISUSE;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_MEMSYS3
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetMemsys3());
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_vfs_oom_test(
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_memdebug_vfs_oom_test;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc>2 ){
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "?INTEGER?");
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( objc==2 ){
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int iNew;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( Tcl_GetIntFromObj(interp, objv[1], &iNew) ) return TCL_ERROR;
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_memdebug_vfs_oom_test = iNew;
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_vfs_oom_test));
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter.
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_malloc_Init(Tcl_Interp *interp){
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct {
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     char *zName;
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     Tcl_ObjCmdProc *xProc;
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     int clientData;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aObjCmd[] = {
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_malloc",             test_malloc                   ,0 },
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_realloc",            test_realloc                  ,0 },
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_free",               test_free                     ,0 },
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "memset",                     test_memset                   ,0 },
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "memget",                     test_memget                   ,0 },
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memory_used",        test_memory_used              ,0 },
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memory_highwater",   test_memory_highwater         ,0 },
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_backtrace", test_memdebug_backtrace       ,0 },
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_dump",      test_memdebug_dump            ,0 },
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_fail",      test_memdebug_fail            ,0 },
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_pending",   test_memdebug_pending         ,0 },
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_settitle",  test_memdebug_settitle        ,0 },
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0 },
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_log",       test_memdebug_log             ,0 },
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_scratch",     test_config_scratch           ,0 },
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_pagecache",   test_config_pagecache         ,0 },
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_alt_pcache",  test_alt_pcache               ,0 },
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_status",             test_status                   ,0 },
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_db_status",          test_db_status                ,0 },
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "install_malloc_faultsim",    test_install_malloc_faultsim  ,0 },
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_heap",        test_config_heap              ,0 },
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_config_error",       test_config_error             ,0 },
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test          ,0 },
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientData c = (ClientData)aObjCmd[i].clientData;
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1439